如何分页一个JPA查询(How to paginate a JPA Query)

2019-08-31 11:35发布

我有样柱提交表格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等哪个是最有效的一个在这种情况呢?

Answer 1:

对于所有的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)例如参数值。



Answer 2:

您可以使用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();
}


Answer 3:

正如我在解释这篇文章 ,你可以使用JPA分页两个实体的查询和原生SQL。

为了限制基础查询ResultSet的大小,JPA Query接口提供setMaxResults方法 。

浏览以下网页需要定位的结果集中的最后一页结束。 为了这个目的,在JPA Query接口提供setFirstResult方法 。

使用分页与JPQL查询看起来如下:

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

因为你需要创建一个标准的API是一样的QueryCriteriaQuery

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


文章来源: How to paginate a JPA Query