关于hibernate:如何使用Spring Data和QueryDSL进行分页执行JPAQuery

How to execute a JPAQuery with pagination using Spring Data and QueryDSL

我的这个请求与queryDSL一起工作良好:

1
2
3
4
5
 Iterable<AO> query_result = new JPAQuery(entityManager).from(ao)
            .leftJoin( ao.lots , lot )
            .leftJoin( ao.acs , ac )
              .where(where).distinct()
                .list(ao);

但是如果我们将其与spring data jpa

1
ao_respository.findAll(Predicate arg0, Pageable arg1);

因为我想返回一个Page,而仅使用queryDSL,如果没有spring data jpa,它不会实现Page

我尝试将where放入Predicate arg0,但出现此异常

1
Undeclared path 'lot '. Add this path as a source to the query to be able to reference it

其中lot被声明为QLot lot = QLot.lot;


我创建了自己的Page类,并执行了如下查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    JPAQuery query = new JPAQuery(entityManager).from(ao)              
            .leftJoin( .. ).fetch()
            .leftJoin( .. ).fetch()
            ...
            .where(where)




    MaPage<AO> page = new MaPage<AO>();
    page.number = pageNumber+1;

    page.content = query.offset(pageNumber*pageSize).limit(pageSize).list(ao);

    page.totalResult = query.count();

我的页面类:

1
2
3
4
5
6
7
8
public class MaPage< T > {

    public List< T > content;
    public int number;
    public Long totalResult;
    public Long totalPages;
    ...
}

它起作用了,但是我得到了这个警告

nov. 21, 2014 6:48:54 AM
org.hibernate.hql.internal.ast.QueryTranslatorImpl list WARN:
HHH000104: firstResult/maxResults specified with collection fetch;
applying in memory!


返回Page

1
2
3
4
5
6
7
8
9
JPAQuery query =
    ...
    .orderBy(getOrderSpecifiers(pageable, MyEntity.class))
    .limit(pageable.getPageSize())
    .offset(pageable.getOffset());

long total = query.fetchCount();
List<MyEntity> content = query.fetch();
return new PageImpl<>(content, pageable, total);

然后我创建了此函数以获取OrderSpecifier

1
2
3
4
5
6
7
8
9
10
11
12
13
private OrderSpecifier[] getOrderSpecifiers(@NotNull Pageable pageable, @NotNull Class klass) {

    // orderVariable must match the variable of FROM
    String className = klass.getSimpleName();
    final String orderVariable = String.valueOf(Character.toLowerCase(className.charAt(0))).concat(className.substring(1));

    return pageable.getSort().stream()
            .map(order -> new OrderSpecifier(
                    Order.valueOf(order.getDirection().toString()),
                    new PathBuilder(klass, orderVariable).get(order.getProperty()))
            )
            .toArray(OrderSpecifier[]::new);
}