I'm currently working on spring boot project. In my project i am using criteria builder for fetch data from postgres database its work fine for smaller data. But didn't work for larger data.so I decided to move to an other options ( JPQL, jdbc template). Could you give suggestions which is fastest way to fetch data in spring boot
( **JPQL, jdbc template, raw query **). Could you give suggestions which is fastest way to fetch data in spring boot
Here are the best approaches for handling large datasets in Spring Boot, ordered by performance:
JdbcTemplate (Fastest)
Native Queries with Streaming
JPQL with Streaming
Pagination
Key recommendations for optimizing large data fetches:
Some code examples // 1. Using JdbcTemplate with Stream
@Service
public class UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void processLargeData() {
String sql = "SELECT * FROM users WHERE active = true";
jdbcTemplate.setFetchSize(1000); // Set appropriate fetch size
jdbcTemplate.query(
sql,
resultSet -> {
while (resultSet.next()) {
// Process each row here
User user = User.builder()
.id(resultSet.getLong("id"))
.name(resultSet.getString("name"))
.build();
processUser(user);
}
}
);
}
}
// 2. Using JPA/JPQL with Streaming
@Service
public class UserJpaService {
@Autowired
private EntityManager entityManager;
@Transactional(readOnly = true)
public void streamUsers() {
String jpql = "SELECT u FROM User u WHERE u.active = true";
try (Stream<User> userStream = entityManager.createQuery(jpql, User.class)
.setHint(QueryHints.FETCH_SIZE, 1000)
.getResultStream()) {
userStream.forEach(this::processUser);
}
}
}
// 3. Using Native Query with Cursor
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM users WHERE active = true",
nativeQuery = true)
@QueryHints(value = {
@QueryHint(name = JDBC_FETCH_SIZE, value = "1000"),
@QueryHint(name = READ_ONLY, value = "true")
})
Stream<User> streamAllUsersWithCursor();
}
// 4. Using Pagination
@Service
public class UserPaginationService {
@Autowired
private UserRepository userRepository;
public void processUsersInBatches() {
int pageSize = 1000;
int pageNumber = 0;
Page<User> userPage;
do {
userPage = userRepository.findAll(PageRequest.of(pageNumber, pageSize));
processUserBatch(userPage.getContent());
pageNumber++;
} while (userPage.hasNext());
}
}