次のような「select * from USERS」という簡単なクエリがあります。また、Pageableを使用してページ分割を有効にします。
このクエリには、指定されたパラメーターがnullかどうかに基づいて、オプションの述語が含まれる場合があります。
たとえば、「code」パラメータが指定されていてnullでない場合、クエリは「select * from USERS where code =:code」になります。
私の知る限り、@ Queryアノテーションを使用してこれを実装することはできません。カスタムリポジトリを実装し、EntityManagerを使用して動的クエリを作成できます。ただし、ページング可能な結果を取得するために「Pageable」をそれとどのように統合できるかわかりません。
どうすればこれを達成できますか?
これは、(基準APIの代替として)QueryDSLを使用してSpring Dataで行うのが非常に簡単です。次のQueryDSLPredicateExecutorのメソッドですぐにサポートされます。制限を適用しない場合は、Predicateとしてnullを渡すことができます。
Page<T> findAll(com.mysema.query.types.Predicate predicate,
Pageable pageable)
QueryDSLの使用はオプションではないかもしれませんが、以下の一連のチュートリアルを見ると、いくつかのアイデアが得られるかもしれません。
あなたが持っているシナリオは、彼のガイドのパート9へのコメントで著者によって実際に議論されています。
Querydslクエリのページ結果の取得は、2つのクエリが必要なので、やや複雑です。1つはエントリの総数、もう1つはページに必要なエントリのリストです。次のスーパークラスを使用できます。
public class QueryDslSupport<E, Q extends EntityPathBase<E>> extends QueryDslRepositorySupport {
public QueryDslSupport(Class<E> clazz) {
super(clazz);
}
protected Page<E> readPage(JPAQuery query, Q qEntity, Pageable pageable) {
if (pageable == null) {
return readPage(query, qEntity, new QPageRequest(0, Integer.MAX_VALUE));
}
long total = query.clone(super.getEntityManager()).count(); // need to clone to have a second query, otherwise all items would be in the list
JPQLQuery pagedQuery = getQuerydsl().applyPagination(pageable, query);
List<E> content = total > pageable.getOffset() ? pagedQuery.list(qEntity) : Collections.<E> emptyList();
return new PageImpl<>(content, pageable, total);
}
}
たとえば、querydsl
を使用してwhere
を構築する必要があります。
_BooleanBuilder where = new BooleanBuilder();
...
if(code != null){
where.and(YOURENTITY.code.eq(code));
}
_
そしてクエリを実行した後
_ JPAQuery query = new JPAQuery(entityManager).from(..)
.leftJoin( .. )
...
.where(where)
_
自分のページを使う
_ MaPage<YOURENTITY> page = new MaPage<YOURENTITY>();
page.number = pageNumber+1;
page.content = query.offset(pageNumber*pageSize).limit(pageSize).list(...);
page.totalResult = query.count();
_
私はそのようにMyPageを作成します
_public class MaPage<T> {
public List<T> content;
public int number;
public Long totalResult;
public Long totalPages;
...
}
_
動作しますが、クエリでフェッチを取得すると、この警告が表示されます
11月21、2014 6:48:54 AM org.hibernate.hql.internal.ast.QueryTranslatorImplリスト
警告:HHH000104:コレクションフェッチで指定されたfirstResult/maxResults。メモリに適用します!
そして、それはあなたの要求を遅くしますだから解決策は、フェッチを取得して@BatchSize(size=10)
を定義し、Hibernate.initialize(....)
を使用してコレクションや他のオブジェクトタイプのデータをフェッチすることです。
ここの情報は時代遅れです。リポジトリに QueryDslPredicateExecutor を実装させると、ページングは無料で利用できます。