JPAクエリでレコードの位置を知るにはどうすればよいですか?
このシグネチャを持つメソッドを多かれ少なかれ実装するページ化された結果を返すサービスがあります。
List<Record> getRecordsPage(long page, int pageSize);
これが呼び出されると、クエリを作成して次のように構成するだけです。
TypedQuery<Record> query = entityManager.createQuery(criteriaQuery);
query.setFirstResult(page * pageSize);
query.setMaxResults(pageSize);
これにより、結果がページングされます。これは期待どおりに機能しており、非常に単純です。
問題
もう 1 つの要件は、特定のレコードを含むページを取得するメソッドを実装することです。次のシグネチャを持つメソッドを実装します。
List<Record> getRecordsPage(Record record, int pageSize);
このメソッドは、レコードが存在する正しいページを生成する必要があります。たとえば、getRecordsPage(RECORD4, 2)
呼び出しの場合、データベースの状態を考慮します。
1. RECORD1
2. RECORD2
3. RECORD3
4. RECORD4
5. RECORD5
返されるページは 2 を含む必要があります[RECORD3, RECORD4]
。
ORDER BY
パラメータは常に設定され、複数のフィールドである可能性があります。
今までの解決策
これまで、次のようないくつかのソリューションがあります。
- まったく良くありませんが、問題は解決します:
提供されたクエリを使用して、ページングなしで id だけを選択し、indexOf
その位置を見つけるために a だけを実行し、その位置に基づいてレコードのページを見つけてから、getRecordsPage(long page, int pageSize)
既に実装されているものを使用して通常のプロセスを実行します。
- データベースとの結合が高いため、あまり良くありません:
私は mySQL を使用しているので、 : のような sql を実行してselect r from (select rownum r, id from t order by x,y) z where z.id = :id
、レコードの位置を返すことができ、それを使用して を呼び出すことができましたgetRecordsPage(long page, int pageSize)
。
良い解決策
要件:
- 複数のフィールドによる順序をサポートするものとします。
- クエリを指定すると、レコードの位置または含まれるレコードのページ オフセットが返されます。
適切な解決策は次のとおりです。
- 純粋な JPA であること。
- レコードの位置を見つけるためだけに、データベースで追加のクエリが実行されても問題ありません。
- ある時点で休止状態が使用されている場合は問題ありません(この場合、休止状態は JPA の背後にあるため)。