Querydsl - 分页功能

9

Jpa QueryDsl中似乎可以像这样使用分页:

return new JPAQueryFactory(getEntityManager())
    .selectFrom(entity)
    .where(where_clause)
    .orderBy(order_by_clause)
    .offset(pageNumber * 20)
    .limit(20)
    .fetchResults();

问题如下:

  • 这是最优的方法吗?fetchResults是否只从数据库中加载20个元素,并进行计数查询以获取有多少实体在数据库中?
  • 或者可能有一些选项,例如.page(2).limit(20)?

是的,我知道Spring-Data已经具有Paging和QueryDsl接口,但由于Spring-Data不支持复杂的“order by”子句,因此我无法使用它:(


我也在使用querydsl,并需要在可分页和排序的存储库之外实现分页。Adil Khalil的答案很有帮助。 - havryliuk
2个回答

18

Querydsl.applyPagination() 也可以被使用。

org.springframework.data.domain.PageImpl;
org.springframework.data.domain.Pageable;

Querydsl querydsl = new Querydsl(entityManager, (new PathBuilderFactory()).create(<EntityClass>.class));
JPQLQuery<?> query = new JPAQuery<>(entityManager);

//TODO: prepare your query here 

//Get the count
Long totalElements = query.fetchCount();

//Apply the pagination
List<?> result = querydsl.applyPagination(pageable, query).fetch();

//return a paged response
return new PageImpl<>(result, pageable, totalElements);

虽然这样做可以实现分页,但我想指出的是,如果你的语句中有类似于SELECT DISTINCT (a, b, c)的情况,其中B和/或C来自不同的实体/表,可能是连接语句的一部分,那么fetchCount()并不一定返回正确的计数。 - undefined

18

时间有点晚了,但希望对某些人有所帮助。

这是最优的方法吗?fetchResults 只会从数据库中加载20个元素,并发出计数查询来获取有多少实体在数据库中吗?

是的-它将发出2个查询。一个用于带有 where 子句的计数,另一个用于获取结果。当您想知道符合条件(where 子句)的记录数量以及按页大小和偏移量提取数据时,这是所需的。使用 .fetchResults() 时,应使用以下方法来获取总计数和如下返回的行。

QueryResults<Tuple> result = query.fetchResults();
int totalCount = result.getTotal();
List<Tuple> rows = result.getResults();

或者可能有一些选项,例如 .page(2).limit(20)?

是的 - 如果你只想获取偏移和页面大小的结果,你应该使用

List<Tuple> rows = query.limit(20).offset(2*20).fetch();

fetch() 方法只会发出一次查询,以获取由指定页面大小和偏移量 '限制' 的结果。


1
我使用了 QueryResults<Tuple> result = query.limit(20).offset(2*20).fetchResults();,看起来工作得很好。 - Radu Linu
1
只是为了让大家知道:fetchResults()方法已经被弃用(fetchCount()方法也是如此),因为在某些情况下无法保证计数查询的准确性。显然,“Blaze persistence”是一个替代方案,但我自己还没有使用过。 - undefined
@Stephanie Blaze 坚持不懈似乎解决了fetchCount()的问题,如果你使用他们的BlazeJPAQuery实现。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接