JPA 分页

本文详细介绍了如何在Java持久性API(JPA)中实现分页查询,包括使用JQL(Java查询语言)的简单方法,如setFirstResult和setMaxResults,以及使用更安全的JPA标准API。文中还讨论了每种方法的优缺点,如通过获取总数和最后一页来实现完整的分页解决方案,并展示了如何避免额外的查询。最后,提供了完整的分页代码示例。
摘要由CSDN通过智能技术生成

1. 概述

本文说明了如何在Java 持久性 API 中实现分页

它解释了如何使用基本 JQL 和更安全、基于标准的 API 进行分页,讨论了每个实现的优点和已知问题。

2. 使用 JQL 和setFirstResult(),setMaxResults()API 进行分页

实现分页的最简单方法是使用Java 查询语言 – 创建一个查询并通过setMaxResultss etFirstResult 对其进行配置:

Query query = entityManager.createQuery("From Foo");
int pageNumber = 1;
int pageSize = 10;
query.setFirstResult((pageNumber-1) * pageSize); 
query.setMaxResults(pageSize);
List <Foo> fooList = query.getResultList();Copy

API 很简单:

  • setFirstResult(int):设置结果集中的偏移位置以开始分页
  • setMaxResults(int):设置页面中应包含的最大实体数

2.1. 总数和最后一页

对于更完整的分页解决方案,我们还需要获取总结果计数

Query queryTotal = entityManager.createQuery
    ("Select count(f.id) from Foo f");
long countResult = (long)queryTotal.getSingleResult();Copy

计算最后一页也非常有用:

int pageSize = 10;
int pageNumber = (int) ((countResult / pageSize) + 1);Copy

请注意,这种获取结果集总数的方法确实需要额外的查询(针对计数)。

3. 使用实体的 ID 使用 JQL 进行分页

一个简单的替代分页策略是首先检索完整的 ID,然后根据这些 ID 检索完整的实体。这样可以更好地控制实体获取 - 但这也意味着它需要加载整个表才能检索 id:

Query queryForIds = entityManager.createQuery(
  "Select f.id from Foo f order by f.lastName");
List<Integer> fooIds = queryForIds.getResultList();
Query query = entityManager.createQuery(
  "Select f from Foo e where f.id in :ids");
query.setParameter("ids", fooIds.subList(0,10));
List<Foo> fooList = query.getResultList();Copy

最后,还要注意,它需要 2 个不同的查询来检索完整结果。

4. 使用标准 API 使用 JPA 进行分页

接下来,让我们看看如何利用 JPA 标准 API来实现分页:

int pageSize = 10;
CriteriaBuilder criteriaBuilder = entityManager
  .getCriteriaBuilder();
CriteriaQuery<Foo> criteriaQuery = criteriaBuilder
  .createQuery(Foo.class);
Root<Foo> from = criteriaQuery.from(Foo.class);
CriteriaQuery<Foo> select = criteriaQuery.select(from);
TypedQuery<Foo> typedQuery = entityManager.createQuery(select);
typedQuery.setFirstResult(0);
typedQuery.setMaxResults(pageSize);
List<Foo> fooList = typedQuery.getResultList();Copy

当目标是创建动态、故障安全查询时,这很有用。与“硬编码”、“基于字符串”的 JQL 或 HQL 查询相比,JPA 条件减少了运行时失败,因为编译器会动态检查查询错误。

使用 JPA 标准以非常简单的方式获取实体总数

CriteriaQuery<Long> countQuery = criteriaBuilder
  .createQuery(Long.class);
countQuery.select(criteriaBuilder.count(
  countQuery.from(Foo.class)));
Long count = entityManager.createQuery(countQuery)
  .getSingleResult();Copy

最终结果是使用 JPA 标准 API 的完整分页解决方案

int pageNumber = 1;
int pageSize = 10;
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

CriteriaQuery<Long> countQuery = criteriaBuilder
  .createQuery(Long.class);
countQuery.select(criteriaBuilder
  .count(countQuery.from(Foo.class)));
Long count = entityManager.createQuery(countQuery)
  .getSingleResult();

CriteriaQuery<Foo> criteriaQuery = criteriaBuilder
  .createQuery(Foo.class);
Root<Foo> from = criteriaQuery.from(Foo.class);
CriteriaQuery<Foo> select = criteriaQuery.select(from);

TypedQuery<Foo> typedQuery = entityManager.createQuery(select);
while (pageNumber < count.intValue()) {
    typedQuery.setFirstResult(pageNumber - 1);
    typedQuery.setMaxResults(pageSize);
    System.out.println("Current page: " + typedQuery.getResultList());
    pageNumber += pageSize;
}Copy

5. 结论

本文探讨了 JPA 中提供的基本分页选项。

有些缺点 - 主要与查询性能有关,但这些缺点通常被改进的控制和整体灵活性所抵消。

正在上传…重新上传取消

这个Spring JPA教程的实现可以在GitHub项目中找到 - 这是一个基于Maven的项目,所以它应该很容易导入和运行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值