最新の安定バージョンについては、Spring Data Commons 3.4.2 を使用してください! |
スクロール
スクロールは、より大きな結果セットのチャンクを反復処理するための、よりきめ細かいアプローチです。スクロールは、安定ソート、スクロール型 (オフセットまたはキーセットベースのスクロール)、および結果の制限で構成されます。プロパティ名を使用して単純な並べ替え式を定義し、クエリの派生を通じて Top
または First
キーワードを使用して静的な結果制限を定義できます。式を連結して、複数の条件を 1 つの式にまとめることができます。
スクロールクエリは Window<T>
を返します。これにより、アプリケーションがクエリ結果全体を消費するまで、スクロール位置の取得を再開して次の Window<T>
を取得できます。結果の次のバッチを取得して Java Iterator<List< …>>
を消費するのと同様に、クエリ結果のスクロールにより、Window.positionAt(…)
を介して ScrollPosition
にアクセスできます。
Window<User> users = repository.findFirst10ByLastnameOrderByFirstname("Doe", ScrollPosition.offset());
do {
for (User u : users) {
// consume the user
}
// obtain the next Scroll
users = repository.findFirst10ByLastnameOrderByFirstname("Doe", users.positionAt(users.size() - 1));
} while (!users.isEmpty() && users.hasNext());
WindowIterator
は、次の Window
の存在をチェックする必要をなくし、ScrollPosition
を適用することにより、Window
間のスクロールを簡素化するユーティリティを提供します。
WindowIterator<User> users = WindowIterator.of(position -> repository.findFirst10ByLastnameOrderByFirstname("Doe", position))
.startingAt(OffsetScrollPosition.initial());
while (users.hasNext()) {
User u = users.next();
// consume the user
}
オフセットを使用したスクロール
オフセットスクロールは、ページネーションと同様に、オフセットカウンターを使用して多数の結果をスキップし、データソースが特定のオフセットで始まる結果のみを返すようにします。この単純なメカニズムにより、大量の結果がクライアントアプリケーションに送信されるのを回避できます。ただし、ほとんどのデータベースでは、サーバーが結果を返す前に完全なクエリ結果を具体化する必要があります。
OffsetScrollPosition
の使用 interface UserRepository extends Repository<User, Long> {
Window<User> findFirst10ByLastnameOrderByFirstname(String lastname, OffsetScrollPosition position);
}
WindowIterator<User> users = WindowIterator.of(position -> repository.findFirst10ByLastnameOrderByFirstname("Doe", position))
.startingAt(OffsetScrollPosition.initial()); (1)
1 | 位置 0 の初期オフセットから開始します。 |
Keyset-Filtering を使用したスクロール
オフセットベースの要件では、サーバーが結果を返す前に、ほとんどのデータベースで結果全体をマテリアライズする必要があります。そのため、クライアントはリクエストされた結果の一部しか表示しませんが、サーバーは完全な結果を構築する必要があり、追加の負荷が発生します。
Keyset-Filtering は、個々のクエリの計算と I/O 要件を削減することを目的として、データベースの組み込み機能を活用することにより、結果サブセットの取得にアプローチします。このアプローチでは、キーをクエリに渡すことでスクロールを再開するキーのセットを維持し、フィルター条件を効果的に修正します。
Keyset-Filtering の核となる考え方は、安定した並べ替え順序を使用して結果の取得を開始することです。次のチャンクにスクロールしたい場合は、並べ替えられた結果内の位置を再構築するために使用される ScrollPosition
を取得します。ScrollPosition
は、現在の Window
内の最後のエンティティのキーセットをキャプチャーします。クエリを実行するために、再構築によって条件句が書き直され、すべての並べ替えフィールドと主キーが含まれるようになります。これにより、データベースは潜在的なインデックスを利用してクエリを実行できるようになります。データベースは、指定されたキーセット位置からはるかに小さな結果を構築するだけでよく、大きな結果を完全にマテリアライズして特定のオフセットに到達するまで結果をスキップする必要はありません。
Keyset-Filtering では、キーセットプロパティ (並べ替えに使用されるもの) が null 非許容である必要があります。この制限は、比較演算子のストア固有の |
KeysetScrollPosition
の使用 interface UserRepository extends Repository<User, Long> {
Window<User> findFirst10ByLastnameOrderByFirstname(String lastname, KeysetScrollPosition position);
}
WindowIterator<User> users = WindowIterator.of(position -> repository.findFirst10ByLastnameOrderByFirstname("Doe", position))
.startingAt(ScrollPosition.keyset()); (1)
1 | 最初から開始し、追加のフィルタリングを適用しないでください。 |
Keyset-Filtering は、データベースに並べ替えフィールドに一致するインデックスが含まれている場合に最適に機能するため、静的並べ替えが適切に機能します。Keyset-Filtering を適用するスクロールクエリでは、並べ替え順序で使用されるプロパティがクエリによって返される必要があり、これらは返されるエンティティにマップされる必要があります。
インターフェースと DTO 射影を使用できますが、キーセット抽出の失敗を避けるために、並べ替えたすべてのプロパティを含めるようにしてください。
Sort
順序を指定するときは、クエリに関連する並べ替えプロパティを含めるだけで十分です。一意のクエリ結果を保証したくない場合は、その必要はありません。キーセットクエリメカニズムは、各クエリ結果が一意であることを保証するために、主キー (または複合主キーの残りの部分) を含めることによって並べ替え順序を修正します。