[Java JDBC] Xử lý ResultSet có kích thước lớn với JdbcTemplate

Chào các bạn, trong bài viết này, chúng ta sẽ cùng tìm hiểu về cách xử lý ResultSet có kích thước lớn với JdbcTemplate

P.S Đã test với Java 8 và Spring JDBC 5.1.4.RELEASE


1. Lấy ra ResultSet có kích thước lớn
1.1 Đầu tiên là cách cơ bản findAll để lấy tất cả dữ liệu từ bảng.

BookRepository.java
Java:
public List<Book> findAll() {
    return jdbcTemplate.query(
            "select * from books",
            (rs, rowNum) ->
                    new Book(
                            rs.getLong("id"),
                            rs.getString("name"),
                            rs.getBigDecimal("price")
                    )
    );

}

Chạy nó, lượng data nhỏ, không vấn đề.

Java:
List<Book> list = bookRepository.findAll();

for (Book book : list) {
    //process it
}

Nếu bảng chứa hơn hàng triệu dòng dữ liệu, RowMapper trong phương thức findAll sẽ bận chuyển đổi đối tượng và đẩy tất cả các đối tượng vào trong một List, nếu kích thước đối tượng lớn hơn dung lượng Java heap còn trống, xem lỗi bên dưới:

Code:
java.lang.OutOfMemoryError: Java heap space

2. Giải pháp
Chúng ta có thể tăng kích thước heap, nhưng giải pháp tốt hơn là sử dụng RowCallbackHandler để xử lý ResultSet lớn trên cơ sở mỗi dòng.

Java:
import org.springframework.jdbc.core.RowCallbackHandler;

    jdbcTemplate.query("select * from books", new RowCallbackHandler() {
        public void processRow(ResultSet resultSet) throws SQLException {
            while (resultSet.next()) {
                String name = resultSet.getString("Name");
                // process it
            }
        }
    });

Download Source Code
$ git clone https://github.com/mkyong/spring-boot.git
$ cd spring-jdbc


Cám ơn các bạn đã theo dõi. Hẹn gặp lại các bạn trong các bài viết sau :D

Bài viết tham khảo tại: https://mkyong.com/spring/spring-jdbctemplate-handle-large-resultset/
 

Bình luận