JPA标准返回页面和总计

Gad*_*adi 6 java jpa criteria

对于分页数据(分页)我需要返回符合我的条件和结果第一页的记录总数.这对于显示用户的信息并计算预期的总页数(在客户端上)非常有用.

目前我运行相同的查询两次,一次是总计数,一次是实际记录.我希望有一种更有效的方式.

可以将这两个查询合并为一次调用数据库吗?

伯爵:

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Long> cq = cb.createQuery(Long.class);
    Root<VersionJpa> r = cq.from(VersionJpa.class);
    Predicate p = cb.conjunction();
    p = // some filtering code define by caller
    cq.where(p);
    cq.select(cb.count(r));
    TypedQuery<Long> tq = em.createQuery(cq);
    return tq.getSingleResult().intValue();
Run Code Online (Sandbox Code Playgroud)

这页纸:

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<VersionJpa> cq = cb.createQuery(VersionJpa.class);
    Root<VersionJpa> root = cq.from(VersionJpa.class);
    Predicate p = cb.conjunction();
    p = // same filtering code as in the count above
    cq.where(p);
    TypedQuery<VersionJpa> tq = em.createQuery(cq);
    // paginatong
    tq.setFirstResults(first); // from caller
    tq.setMaxResults(max);     // from caller
    return tq.getResultList();
Run Code Online (Sandbox Code Playgroud)

per*_*ssf 2

即使假设存在一个检索记录计数和分页记录本身的高效查询,您也需要为用户访问的每个页面对数据库执行额外的调用。这使得访问第一页期间获得的性能增益可以忽略不计。

我的意思是:要访问第一页,您需要:

  1. 不分页过滤的项目总数
  2. 已过滤的项目,其分页为第 1 页

要访问其他页面,您不再需要计数查询。您只需要第 x 页的筛选项目。

展开 n 个页面后,即使使用您正在寻找的优化,您也会执行 n 次调用,而不是非优化版本的 n+1 次调用。所以,我不会花太多时间去思考这个问题。

您只需在实现中小心,不要在不必要时执行记录计数:仅在用户更改过滤后才需要它。