Câu trả lời của Ken về cơ bản là đúng nhưng tôi muốn nói về "tại sao bạn muốn sử dụng cái này hơn cái kia?" một phần câu hỏi của bạn
Khái niệm cơ bản
Giao diện cơ sở bạn chọn cho kho lưu trữ của bạn có hai mục đích chính. Đầu tiên, bạn cho phép cơ sở hạ tầng kho lưu trữ dữ liệu Spring tìm giao diện của bạn và kích hoạt việc tạo proxy để bạn đưa các phiên bản của giao diện vào máy khách. Mục đích thứ hai là kéo theo nhiều chức năng cần thiết vào giao diện mà không phải khai báo các phương thức bổ sung.
Các giao diện phổ biến
Thư viện lõi của Spring Data có hai giao diện cơ bản trưng bày một bộ chức năng chuyên dụng:
CrudRepository
- Phương pháp CRUD
PagingAndSortingRepository
- phương pháp phân trang và phân loại (mở rộng CrudRepository
)
Giao diện cửa hàng cụ thể
Các mô-đun cửa hàng riêng lẻ (ví dụ: JPA hoặc MongoDB) hiển thị các tiện ích mở rộng dành riêng cho cửa hàng của các giao diện cơ sở này để cho phép truy cập vào chức năng dành riêng cho cửa hàng như xả nước hoặc tạo khối chuyên dụng có tính đến một số chi tiết cụ thể của cửa hàng. Một ví dụ cho điều này là deleteInBatch(…)
các JpaRepository
mà là khác nhau từ delete(…)
khi nó sử dụng một truy vấn để xóa các đối tượng nhất định mà là performant hơn nhưng đi kèm với các tác dụng phụ của không kích hoạt các thác JPA định nghĩa (như định nghĩa spec nó).
Chúng tôi thường khuyên không nên sử dụng các giao diện cơ sở này vì chúng phơi bày công nghệ bền bỉ cơ bản cho khách hàng và do đó thắt chặt sự kết nối giữa chúng và kho lưu trữ. Thêm vào đó, bạn có một chút khác biệt so với định nghĩa ban đầu của một kho lưu trữ về cơ bản là "một bộ sưu tập các thực thể". Vì vậy, nếu bạn có thể, ở lại với PagingAndSortingRepository
.
Giao diện cơ sở kho lưu trữ tùy chỉnh
Nhược điểm của trực tiếp phụ thuộc vào một trong các giao diện cơ sở được cung cấp là hai lần. Cả hai có thể được coi là lý thuyết nhưng tôi nghĩ rằng họ quan trọng để nhận thức được:
- Tùy thuộc vào giao diện kho lưu trữ dữ liệu Spring kết hợp giao diện kho lưu trữ của bạn với thư viện. Tôi không nghĩ rằng đây là một vấn đề cụ thể vì có thể bạn sẽ sử dụng các khái niệm trừu tượng như
Page
hoặc Pageable
trong mã của bạn. Spring Data không khác biệt với bất kỳ thư viện mục đích chung nào khác như commons-lang hoặc Guava. Miễn là nó mang lại lợi ích hợp lý, nó vẫn ổn.
- Bằng cách mở rộng
CrudRepository
, ví dụ , bạn đưa ra một bộ phương pháp kiên trì hoàn chỉnh cùng một lúc. Điều này có thể cũng tốt trong hầu hết các trường hợp, nhưng bạn có thể gặp phải tình huống mà bạn muốn có được quyền kiểm soát chi tiết hơn đối với các phương thức được đưa ra, ví dụ: để tạo một phương thức ReadOnlyRepository
không bao gồm save(…)
và delete(…)
phương thức CrudRepository
.
Giải pháp cho cả hai nhược điểm này là tạo giao diện kho lưu trữ cơ sở của riêng bạn hoặc thậm chí là một bộ chúng. Trong rất nhiều ứng dụng tôi đã thấy một cái gì đó như thế này:
interface ApplicationRepository<T> extends PagingAndSortingRepository<T, Long> { }
interface ReadOnlyRepository<T> extends Repository<T, Long> {
// Al finder methods go here
}
Giao diện kho lưu trữ đầu tiên là một số giao diện cơ sở cho mục đích chung thực sự chỉ sửa điểm 1 mà còn liên kết loại ID để đảm Long
bảo tính nhất quán. Giao diện thứ hai thường có tất cả các find…(…)
phương thức được sao chép từ CrudRepository
và PagingAndSortingRepository
không hiển thị các phương thức thao tác. Đọc thêm về cách tiếp cận đó trong tài liệu tham khảo .
Tóm tắt - tl; dr
Việc trừu tượng hóa kho lưu trữ cho phép bạn chọn kho lưu trữ cơ sở hoàn toàn do bạn đáp ứng nhu cầu kiến trúc và chức năng. Sử dụng những cái được cung cấp ngoài hộp nếu chúng phù hợp, tạo các giao diện cơ sở kho lưu trữ của riêng bạn nếu cần thiết. Tránh xa các giao diện kho lưu trữ cụ thể trừ khi không thể tránh khỏi.