2013-10-31 8 views
11

私は以下のような簡単なクエリを "select * from USERS"とします。また、Pageableを使用してページネーションを有効にします。Springデータ動的クエリーを使用するJPAページネーション(Pageable)

このクエリは、指定されたパラメータがnullかどうかに基づいて、オプションの述語を持つことがあります。

たとえば、 "code"パラメータが指定され、nullでない場合、クエリは "select * from USERS where code =:code"になります。

私が知る限り、@Queryアノテーションを使用してこれを実装することはできません。カスタムリポジトリを実装し、EntityManagerを使用して動的クエリを作成することができます。 しかし、どのようにページングされた結果を得るために "Pageable"をどのように統合できるかはわかりません。

どうすればこの問題を解決できますか?

答えて

10

これは、(条件APIの代わりに)QueryDSLを使用してSpringデータで行うのが非常に簡単です。それは、何の制限が適用されない場合は、単に述語としてnullを渡すことができQueryDSLPredicateExecutorの次のような方法で、箱から出してサポートされています:あなたが見れば

QueryDSLを使用して
Page<T> findAll(com.mysema.query.types.Predicate predicate, 
       Pageable pageable) 

は、しかし、あなたのための選択肢ではないかもしれません次の一連のチュートリアルでは、いくつかのアイデアを得るかもしれません。

http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-nine-conclusions/

あなたが持っているシナリオは、実際に彼のガイドの一部9にコメントで著者によって議論されています。

+0

QueryDslRepositorySupportを使用している場合でも、#getQuerydsl()を使用して基礎となるquerydslインスタンスを公開するため、この機能にアクセスできます – chrismarx

1

あなたはquerydslを使用して、where例えばnullでないパラメータに依存

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(); 
独自のページを使用してクエリを実行を構築する必要が

私はそのようなMyページを作成します

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 list
WARN:HHH000104:firstResult/maxResultsがコレクションフェッチで指定されています。メモリに適用!解決策は、フェッチの乗り心地を取得し、@BatchSize(size=10)を定義し、コレクションや他のオブジェクト型のデータをフェッチするためにHibernate.initialize(....)を使用することですので

は、それはあなたの要求が遅くなります。エントリの合計数に1つ、そしてあなたがページで必要な項目のリストについては、1:あなたは2つのクエリを必要とするので、querydslクエリの

Display data from related entities to avoid the lazy initialization exception with setting up @BatchSize

How to execute a JPAQuery with pagination using Spring Data and QueryDSL

3

の取得ページの結果は何とか複雑になります。ここでの情報は時代遅れである

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); 
    } 

} 
+0

ただし、applyPaginationメソッドはJPQLQueryオブジェクトを使用します – Tisha

0

: 次スーパークラスを使用することができます。リポジトリにQueryDslPredicateExecutorを実装し、ページングは​​無料で提供されます。

関連する問題