Tôi thấy rằng cách tiêu chuẩn để truy cập dưới dạng danh sách là thông qua các phương thức query()
thay vì bất kỳ phương pháp nào khác. Sự khác biệt chính giữa query
và các phương pháp khác là bạn sẽ phải triển khai một trong các giao diện gọi lại (hoặc RowMapper
, RowCallbackHandler
hoặc ResultSetExtractor
) để xử lý tập hợp kết quả của bạn.
A RowMapper
có khả năng là những gì bạn sẽ thấy mình sử dụng phần lớn thời gian. Nó được sử dụng khi mỗi hàng của tập kết quả tương ứng với một đối tượng trong danh sách của bạn. Bạn chỉ phải thực hiện một phương thức mapRow
nơi bạn điền loại đối tượng đi vào hàng của bạn và trả về nó. Mùa xuân cũng có một số BeanPropertyRowMapper
có thể điền các đối tượng vào danh sách thông qua kết hợp tên thuộc tính bean với tên cột (NB lớp này là để thuận tiện không thực hiện).
A RowCallbackHandler
hữu ích hơn khi bạn cần kết quả không chỉ là một danh sách đơn giản. Bạn sẽ phải tự mình quản lý đối tượng trả về bạn đang sử dụng phương pháp này. Tôi thường thấy mình sử dụng điều này khi tôi cần một cấu trúc bản đồ làm kiểu trả về của tôi (tức là cho dữ liệu được nhóm cho một bảng cây hoặc nếu tôi tạo một bộ nhớ cache tùy chỉnh dựa trên khóa chính).
A ResultSetExtractor
được sử dụng khi bạn muốn kiểm soát việc lặp lại kết quả. Bạn ngụ ý một phương thức extractData
sẽ là giá trị trả về của cuộc gọi đến query
. Tôi chỉ thấy mình sử dụng điều này nếu tôi phải xây dựng một số cấu trúc dữ liệu tùy chỉnh phức tạp hơn để xây dựng bằng cách sử dụng một trong hai giao diện gọi lại khác.
Phương thức queryForList()
có giá trị trong đó bạn không phải triển khai các phương thức gọi lại này. Có hai cách sử dụng queryForList. Đầu tiên là nếu bạn chỉ truy vấn một cột đơn từ cơ sở dữ liệu (ví dụ danh sách các chuỗi), bạn có thể sử dụng các phiên bản của phương thức lấy Class làm đối số để tự động cung cấp cho bạn danh sách các đối tượng duy nhất của các lớp đó .
Khi gọi các triển khai khác của queryForList()
bạn sẽ nhận được danh sách trở lại với mỗi mục nhập là bản đồ cho từng cột. Trong khi điều này là tốt đẹp ở chỗ bạn được lưu các chi phí bằng văn bản các phương pháp gọi lại, giao dịch với cấu trúc dữ liệu này là khá khó sử dụng. Bạn sẽ thấy mình thực hiện rất nhiều thao tác truyền vì giá trị của bản đồ là loại Object
.
Tôi chưa bao giờ thấy phương pháp queryForRowSet
được sử dụng trong môi trường hoang dã. Điều này sẽ tải toàn bộ kết quả của truy vấn vào một đối tượng CachedRowSet
bị Wapped bởi một Spring SqlRowSet. Tôi thấy một nhược điểm lớn trong việc sử dụng đối tượng này ở chỗ nếu bạn đang đi qua các SqlRowSet
xung quanh các lớp khác của ứng dụng của bạn, bạn đang ghép nối các lớp đó với việc triển khai truy cập dữ liệu của mình.
Bạn không nên thấy bất kỳ khác biệt hiệu suất lớn nào giữa bất kỳ cuộc gọi nào ngoại trừ như tôi đã đề cập với BeanPropertyRowMapper
. Nếu bạn đang làm việc với một số thao tác phức tạp của một tập hợp kết quả lớn, bạn có thể nhận được một số lợi ích hiệu suất từ việc viết một tối ưu hóa ResultSetExtractor
cho trường hợp cụ thể của bạn.
Nếu bạn muốn tìm hiểu thêm, tôi sẽ tham khảo Spring JDBC documentation và JavaDoc for the classes I've mentioned. Bạn cũng có thể xem một số sách trong Spring Framework. Mặc dù nó có một chút ngày Java Development with the Spring Framework có một phần rất tốt về làm việc với khung công tác JDBC. Hầu hết tất cả, tôi sẽ nói chỉ cần thử viết một số mã với mỗi phương pháp và xem những gì làm việc tốt nhất cho bạn.
AFIK phương pháp truy vấn tương thích Java 5 có sẵn trong JDBCTemplate cũng như trong Spring 3 – Adrian
Bây giờ tôi đã kiểm tra, JdbcTemplate không sử dụng Generics trong Spring 2.5.6 nhưng nó là 3.0.0. Tôi ngửi thấy một sự phản đối trong tương lai ... :) – Esko
SimpleJdbcTemplate hiện không được chấp nhận – Helenesh