web-dev-qa-db-ja.com

JPAクエリにページ番号を付ける方法

他のプロパティの中で、IDNameCodeのような列を持つ送信テーブルがあります。私の要件は、前述のプロパティに基づいてレコードを検索し、ページ分割されたセットを返すことです。

これは私が探しているものの疑似コードです:

searchSubmission(searchFilter sf,pageIndex,noOfRecords) {
   query = 'from submisssion where code=sf.code or id=sf.id order by id start_from (pageIndex*noOfRecords) limit noOfRecords'
   return result();
}

CriteriaBuilderNamedQueryなどの多くのオプションがあるようです。この状況で最も効率的なオプションはどれですか。

17
Tapan Chandra

すべてのJPAクエリオブジェクト(ネイティブSQLクエリを除く)では、setMaxResults(int)およびsetFirstResult(int)メソッドを介してページ付けを使用します。例えば:

  return em.createNamedQuery("yourqueryname", YourEntity.class)
      .setMaxResults(noOfRecords)
      .setFirstResult(pageIndex * noOfRecords)
      .getResultList();

JPAがページ付けを実行します。

名前付きクエリは事前定義されており、キャッシュできますが、他のタイプは動的に作成されます。
したがって、選択肢は次のようにJPQLを使用することです。

Query query = em.createQuery("SELECT s FROM Submission s WHERE s.code = :code or s.id = :id ORDER BY s.id", Submission.class);

または、CriteriaBuilder apiを使用して同様のクエリを作成します。

    CriteriaBuilder qb = em.getCriteriaBuilder();
    CriteriaQuery<Submission> cq = qb.createQuery(Submission.class);

    Root<Submission> root = cq.from(Submission.class);
    cq.where( qb.or( 
        qb.equal(root.get("code"), qb.parameter(String.class, "code")),
        qb.equal(root.get("id"), qb.parameter(Integer.class, "id"))
    ));
    Query query = em.createQuery(cq);

たとえば、query.setParameter( "id"、sf.id)を使用してパラメータ値を設定することを忘れないでください。

36
Chris

リポジトリメソッドでPageableを使用できます

@Repository
public interface StateRepository extends JpaRepository<State, Serializable> {

@Query("select state from State state where state.stateId.stateCode = ?1")
public State findStateByCode(String code, Pageable pageable);

}

また、サービスレイヤーでは、Pageableオブジェクトを作成できます。

@Autowire
StateRepository stateRepository;

public State findStateServiceByCode(String code, int page, int size) {
    Pageable pageable = new PageRequest(page, size);
    Page<Order> statePage = stateRepository.findStateByCode(code, pageable);
    return statePage.getContent();
}
4
sendon1982

この記事 で説明したように、エンティティクエリとネイティブSQLの両方にJPAページネーションを使用できます。

基になるクエリのResultSetサイズを制限するために、JPA Queryインターフェースには setMaxResults method が用意されています。

次のページに移動するには、最後のページが終了した場所に結果セットを配置する必要があります。この目的のために、JPA Queryインターフェースは setFirstResult method を提供します。

JPQLクエリでページネーションを使用すると、次のようになります。

List<Post> posts = entityManager
.createQuery(
    "select p " +
    "from Post p " +
    "order by p.createdOn ")
.setFirstResult(10)
.setMaxResults(10)
.getResultList();

QueryからCriteriaQueryを作成する必要があるため、基準APIはまったく同じです。

CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Post> cq = qb.createQuery(Post.class);

Root<Post> root = cq.from(Post.class);
cq.orderBy(qb.asc(root.get("createdOn")));

List<Post> posts = em
.createQuery(cq)
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
1
Vlad Mihalcea