Spring Data JPA 中的滾動 API
1. 概述
Spring Data Commons是Spring Data 項目的一部分,其中包含管理持久層的接口和實現。 Scroll API 是 Spring Data Commons 提供的功能之一,用於處理從數據庫讀取的大型結果。
在本教程中,我們將通過示例探索 Scroll API。
2. 依賴關係
Spring Boot 3.1 版本中添加了 Scroll API 支持。 Spring Data Commons 已包含在 Spring Data JPA 中。因此,添加 Spring Data JPA 3.1 版本就足以獲得 Scroll API 功能:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>3.1.0</version>
</dependency>
最新的庫版本可以在 Maven 中央存儲庫中找到。
3.實體類
出於示例目的,我們將使用BookReview
實體,其中包含不同用戶評論的各種書籍的書評評級:
@Entity
@Table(name="BOOK_REVIEWS")
public class BookReview {
@Id
@GeneratedValue(strategy= GenerationType.SEQUENCE, generator = "book_reviews_reviews_id_seq")
@SequenceGenerator(name = "book_reviews_reviews_id_seq", sequenceName = "book_reviews_reviews_id_seq", allocationSize = 1)
private Long reviewsId;
private String userId;
private String isbn;
private String bookRating;
// getters and setters
}
4. 滾動API
Scroll API 提供了按塊迭代大型結果的功能。**它提供穩定的排序、滾動類型和結果限制。**
我們可以使用屬性名稱定義簡單的排序表達式,並通過查詢派生使用Top
或First
定義靜態結果限制。
4.1.使用偏移過濾進行滾動
在下面的示例中,我們使用查詢派生通過評級參數和OffsetScrollPosition
查找前五本書:
public interface BookRepository extends Repository<BookReview, Long> {
Window<BookReview> findFirst5ByBookRating(String bookRating, OffsetScrollPosition position);
Window<BookReview> findFirst10ByBookRating(String bookRating, OffsetScrollPosition position);
Window<BookReview> findFirst3ByBookRating(String bookRating, KeysetScrollPosition position);
}
由於我們已經定義了存儲庫方法,因此我們可以在邏輯類中使用它們來獲取前五本書並繼續迭代,直到得到最後一個結果。
在迭代時,我們需要通過查詢來檢查下一個窗口是否存在:
public List<BookReview> getBooksUsingOffset(String rating) {
OffsetScrollPosition offset = ScrollPosition.offset();
Window<BookReview> bookReviews = bookRepository.findFirst5ByBookRating(rating, offset);
List<BookReview> bookReviewsResult = new ArrayList<>();
do {
bookReviews.forEach(bookReviewsResult::add);
bookReviews = bookRepository.findFirst5ByBookRating(rating, (OffsetScrollPosition) bookReviews.positionAt(bookReviews.size() - 1));
} while (!bookReviews.isEmpty() && bookReviews.hasNext());
return bookReviewsResult;
}
我們可以通過使用WindowIterator
來簡化我們的邏輯,它提供了滾動瀏覽大結果的實用程序,而無需檢查下一個窗口和ScrollPosition
:
public List<BookReview> getBooksUsingOffSetFilteringAndWindowIterator(String rating) {
WindowIterator<BookReview> bookReviews = WindowIterator.of(position -> bookRepository
.findFirst5ByBookRating("3.5", (OffsetScrollPosition) position)).startingAt(ScrollPosition.offset());
List<BookReview> bookReviewsResult = new ArrayList<>();
bookReviews.forEachRemaining(bookReviewsResult::add);
return bookReviewsResult;
}
偏移滾動的工作原理類似於分頁,它通過從大結果中跳過一定數量的記錄來返回預期結果。雖然我們只能看到請求結果的一部分,但服務器需要構建完整的結果,這會導致額外的負載。
我們可以使用鍵集過濾來避免這種行為。
4.2.使用鍵集過濾滾動
鍵集過濾有助於使用數據庫的內置功能檢索結果子集,旨在減少單個查詢的計算和 IO 要求。
數據庫只需要從給定的鍵集位置構造較小的結果,而無需實現較大的完整結果:
public List<BookReview> getBooksUsingKeySetFiltering(String rating) {
WindowIterator<BookReview> bookReviews = WindowIterator.of(position -> bookRepository
.findFirst5ByBookRating(rating, (KeysetScrollPosition) position))
.startingAt(ScrollPosition.keyset());
List<BookReview> bookReviewsResult = new ArrayList<>();
bookReviews.forEachRemaining(bookReviewsResult::add);
return bookReviewsResult;
}
5. 結論
在本文中,我們探討了 Spring Data Commons 庫提供的 Scroll API。 Scroll API 支持根據偏移位置和過濾條件以較小的塊讀取大結果。
Scroll API 支持使用 offset 和 keyset 進行過濾。雖然基於偏移的過濾需要在數據庫中具體化整個結果,但鍵集通過構造較小的結果來幫助減少數據庫上的計算和 IO 負載。
與往常一樣,示例代碼可以在 GitHub 上獲取。