Sau khi đọc this article, tôi muốn sử dụng Spring để truyền kết quả truy vấn cơ sở dữ liệu trực tiếp tới phản hồi JSON để đảm bảo sử dụng bộ nhớ liên tục (không tải một bộ tham số List
trong bộ nhớ).Stream resource resource với Spring MVC
Tương tự như những gì được thực hiện trong bài viết với Hibernate, tôi đã ráp một đối tượng greetingRepository
trả về luồng nội dung cơ sở dữ liệu dựa trên JdbcTemplate
. Trong việc thực hiện điều đó, tôi tạo ra một iterator trong truy vấn ResultSet
, và tôi trả lại dòng như sau:
return StreamSupport.stream(spliterator(), false).onClose(() -> {
log.info("Closing ResultSetIterator stream");
JdbcUtils.closeResultSet(resultSet);
});
tức là với một phương pháp onClose()
đảm bảo rằng cơ bản ResultSet
sẽ đóng cửa nếu dòng được khai báo trong một cấu trúc try-with-resources
:
try(Stream<Greeting> stream = greetingRepository.stream()) {
// operate on the stream
} // ResultSet underlying the stream will be guaranteed to be closed
Nhưng như trong bài viết này, tôi muốn dòng này để được tiêu thụ bởi một ánh xạ đối tượng tùy chỉnh (các tăng cường MappingJackson2HttpMessageConverter
định nghĩa trong bài viết). Nếu chúng ta lấy try-with-resources
cần sang một bên, đây là khả thi như sau:
@RequestMapping(method = GET)
Stream<GreetingResource> stream() {
return greetingRepository.stream().map(GreetingResource::new);
}
Tuy nhiên như một đồng nghiệp nhận xét ở dưới cùng của bài viết đó, điều này không chăm sóc đóng nguồn lực tiềm ẩn.
Trong ngữ cảnh của Spring MVC, làm thế nào tôi có thể truyền từ cơ sở dữ liệu tất cả các cách vào một phản ứng JSON và vẫn đảm bảo rằng ResultSet
sẽ bị đóng? Bạn có thể cung cấp một giải pháp ví dụ cụ thể không?
Tôi không nghĩ rằng vấn đề của bạn là rò rỉ tài nguyên: Spring chắc chắn sẽ cam kết giao dịch và giải phóng kết nối, đóng cửa quá mức kết quả của bạn. Nhưng tôi mong đợi vấn đề ngược lại: làm thế nào để bạn quản lý rằng kết nối tồn tại trong lớp xem? Tôi dựa vào 'OpenSessionInViewInterceptor' cho rằng, đó là Hibernate cụ thể. –
Phải, trong kịch bản thử nghiệm của tôi, tôi quên sử dụng các giao dịch, với chúng tôi không thể truyền đến lớp xem nữa (ngoài ra tôi sử dụng MySQL, vì vậy tôi không may mắn). Tôi kết luận rằng việc truyền trực tuyến đến lớp xem là hấp dẫn như có khả năng hiệu quả và khá thanh lịch, nhưng đáng buồn là vẫn khó sử dụng trong thực tế. –
Vẫn không đủ hỗ trợ cho việc này. Đó là biên giới hoang dã. Tôi hy vọng nó bắt được, mặc dù, bởi vì kiến trúc Java cho đến nay đã được rất nhiều thiếu trong bộ phận này. –