diff --git a/spring-batch-2/pom.xml b/spring-batch-2/pom.xml
index 8205853108e3..69df5cc8166f 100644
--- a/spring-batch-2/pom.xml
+++ b/spring-batch-2/pom.xml
@@ -104,6 +104,11 @@
+
+ com.graphql-java
+ java-dataloader
+ 3.2.0
+
diff --git a/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/DataLoaderApp.java b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/DataLoaderApp.java
new file mode 100644
index 000000000000..2228c6b9a4e8
--- /dev/null
+++ b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/DataLoaderApp.java
@@ -0,0 +1,13 @@
+package com.baeldung.dataloaderbatchprocessing;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class DataLoaderApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(DataLoaderApp.class, args);
+ }
+}
+
diff --git a/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/UserDataLoader.java b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/UserDataLoader.java
new file mode 100644
index 000000000000..0f56bc3e443c
--- /dev/null
+++ b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/UserDataLoader.java
@@ -0,0 +1,37 @@
+package com.baeldung.dataloaderbatchprocessing;
+
+import org.dataloader.BatchLoader;
+import org.dataloader.DataLoader;
+import org.dataloader.DataLoaderFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.baeldung.dataloaderbatchprocessing.entity.User;
+import com.baeldung.dataloaderbatchprocessing.service.UserService;
+
+@Component
+public class UserDataLoader {
+
+ private final UserService userService;
+
+ public UserDataLoader(UserService userService) {
+ this.userService = userService;
+ }
+
+ public DataLoader createUserLoader() {
+ BatchLoader userBatchLoader = ids -> {
+ return userService.getUsersByIds(ids)
+ .thenApply(users -> {
+ Map userMap = users.stream()
+ .collect(Collectors.toMap(User::getId, user -> user));
+ return ids.stream()
+ .map(userMap::get)
+ .collect(Collectors.toList());
+ });
+ };
+
+ return DataLoaderFactory.newDataLoader(userBatchLoader);
+ }
+}
diff --git a/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/entity/User.java b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/entity/User.java
new file mode 100644
index 000000000000..25a2a3bd8953
--- /dev/null
+++ b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/entity/User.java
@@ -0,0 +1,19 @@
+package com.baeldung.dataloaderbatchprocessing.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Entity
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+public class User {
+
+ @Id
+ private String id;
+ private String name;
+}
+
diff --git a/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/repository/UserRepository.java b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/repository/UserRepository.java
new file mode 100644
index 000000000000..2fcedde9478c
--- /dev/null
+++ b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/repository/UserRepository.java
@@ -0,0 +1,9 @@
+package com.baeldung.dataloaderbatchprocessing.repository;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.baeldung.dataloaderbatchprocessing.entity.User;
+
+public interface UserRepository extends JpaRepository {
+}
+
diff --git a/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/service/UserService.java b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/service/UserService.java
new file mode 100644
index 000000000000..3e258184c53e
--- /dev/null
+++ b/spring-batch-2/src/main/java/com/baeldung/dataloaderbatchprocessing/service/UserService.java
@@ -0,0 +1,22 @@
+package com.baeldung.dataloaderbatchprocessing.service;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import com.baeldung.dataloaderbatchprocessing.entity.User;
+import com.baeldung.dataloaderbatchprocessing.repository.UserRepository;
+
+@Service
+public class UserService {
+ private final UserRepository userRepository;
+
+ public UserService(UserRepository userRepository) {
+ this.userRepository = userRepository;
+ }
+
+ public CompletableFuture> getUsersByIds(List ids) {
+ return CompletableFuture.supplyAsync(() -> userRepository.findAllById(ids));
+ }
+}
+
diff --git a/spring-batch-2/src/test/java/com/baeldung/dataloaderbatchprocessing/DataLoaderUnitTest.java b/spring-batch-2/src/test/java/com/baeldung/dataloaderbatchprocessing/DataLoaderUnitTest.java
new file mode 100644
index 000000000000..d613d9e364e0
--- /dev/null
+++ b/spring-batch-2/src/test/java/com/baeldung/dataloaderbatchprocessing/DataLoaderUnitTest.java
@@ -0,0 +1,57 @@
+package com.baeldung.dataloaderbatchprocessing;
+
+import com.baeldung.dataloaderbatchprocessing.entity.User;
+import com.baeldung.dataloaderbatchprocessing.service.UserService;
+
+import org.dataloader.DataLoader;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.*;
+
+@SpringBootTest(classes = DataLoaderApp.class)
+public class DataLoaderUnitTest {
+
+ private UserService userService;
+ private UserDataLoader loaderFactory;
+
+ @BeforeEach
+ void setUp() {
+ userService = mock(UserService.class);
+ loaderFactory = new UserDataLoader(userService);
+ }
+
+ @Test
+ void givenThreeUsers_whenUsingDataLoader_thenLoadUsersInSingleDBCall() throws Exception {
+ User user1 = new User("101", "User_101");
+ User user2 = new User("102", "User_102");
+ User user3 = new User("103", "User_103");
+
+ List users = Arrays.asList(user1, user2, user3);
+
+ when(userService.getUsersByIds(Arrays.asList("101", "102", "103"))).thenReturn(CompletableFuture.completedFuture(users));
+
+ DataLoader userLoader = loaderFactory.createUserLoader();
+
+ CompletableFuture future1 = userLoader.load("101");
+ CompletableFuture future2 = userLoader.load("102");
+ CompletableFuture future3 = userLoader.load("103");
+
+ userLoader.dispatch();
+
+ assertEquals("User_101", future1.get()
+ .getName());
+ assertEquals("User_102", future2.get()
+ .getName());
+ assertEquals("User_103", future3.get()
+ .getName());
+
+ verify(userService, times(1)).getUsersByIds(Arrays.asList("101", "102", "103"));
+ }
+}