繁体   English   中英

在 JPA EntityManager createNativeQuery 中实现分页

[英]Implementing pagination in JPA EntityManager createNativeQuery

我正在使用JPA EntityManager createNativeQuery编写查询,我想应用分页。 以下是我到目前为止实现的代码:

private static final int NO_OF_RESULTS_IN_A_PAGE = 30;

public Page<Car> getFilteredCars(int page, String model, String manufacturedYear) {
    Pageable pageable = PageRequest.of(page, NO_OF_RESULTS_IN_A_PAGE, Sort.by("addedDate").descending());
    StringBuilder sb = new StringBuilder("SELECT c.* FROM car c WHERE c.model = ").append(model).append(" AND");
    if(manufacturedYear != null) {
        sb.append(" c.manufactured_year = ").append(manufacturedYear).append(" AND");
    }
    sb.append(" c.for_sale = true ORDER BY c.added_date DESC");

    Query query = entityManager.createNativeQuery(sb.toString(), Car.class);
    query.setFirstResult(page * NO_OF_RESULTS_IN_A_PAGE);
    query.setMaxResults((page * NO_OF_RESULTS_IN_A_PAGE) + NO_OF_RESULTS_IN_A_PAGE);

    Page<Car> results = new PageImpl<>(query.getResultList(), pageable, 0);
    return results;
}

问题是在new PageImpl<>构造函数中,我必须将项目总数作为第三个参数传递。 在查询运行之前,我不知道有多少项目。 如果我传递 0(如上面的代码),我只会返回第一页,即使数据库中实际上有超过 1000 个项目,总项目也将是 30。 PageImpl还有一个更简单的构造函数,它只接受一个参数( query.getResultList() ),但结果将是未分页的。 这导致我运行了两次查询,一次是获取从查询返回的项目总数(未分页),然后使用它来获取分页结果。 显然,必须有更好的方法来实现这一点,而我一直无法弄清楚。

请注意,我的实际查询比上面描述的涉及多个 if-else 条件检查的查询要复杂得多,因此不适合通过简单的JpaRepository实现或使用可以轻松实现分页的@Query进行查询。

我担心在执行实际的 select 之前,除了让数据库通过附加查询计算汽车总数之外别无他法。 喜欢

SELECT count(1) FROM car c WHERE c.model = ...

简单计数比返回 n>1 行的选择要快得多。 当然,计数会减慢执行速度,但在现代数据库上,这只会花费几毫秒——我们人类无法识别的东西;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM