我有一个简单的查询,如下所示“select * from USERS”。我还使用Pageable来启用分页。
此查询可能具有基于给定参数为null的可选谓词。
例如,如果给出“code”参数而不是null,则查询变为 “select * from USERS where code =:code”;
据我所知,我无法使用@Query注释实现此功能。我可以实现自定义存储库并使用EntityManager来创建动态查询。 但是,我不确定如何将“Pageable”与其相结合以获得分页结果。
我怎样才能做到这一点?
答案 0 :(得分:14)
使用QueryDSL在Spring数据中很容易做到(作为标准API的替代)。使用QueryDSLPredicateExecutor的以下方法开箱即用,如果不应用限制,您可以将null作为谓词传递:
Page<T> findAll(com.mysema.query.types.Predicate predicate,
Pageable pageable)
使用QueryDSL可能不适合您,但是如果您查看以下系列教程,您可能会得到一些想法。
作者在他的指南第9部分的评论中实际讨论了你所拥有的场景。
答案 1 :(得分:4)
获取querydsl查询的页面结果有点复杂,因为您需要两个查询:一个用于条目总数,另一个用于页面中所需的条目列表。 您可以使用以下超类:
public class QueryDslSupport<E, Q extends EntityPathBase<E>> extends QueryDslRepositorySupport {
public QueryDslSupport(Class<E> clazz) {
super(clazz);
}
protected Page<E> readPage(JPAQuery query, Q qEntity, Pageable pageable) {
if (pageable == null) {
return readPage(query, qEntity, new QPageRequest(0, Integer.MAX_VALUE));
}
long total = query.clone(super.getEntityManager()).count(); // need to clone to have a second query, otherwise all items would be in the list
JPQLQuery pagedQuery = getQuerydsl().applyPagination(pageable, query);
List<E> content = total > pageable.getOffset() ? pagedQuery.list(qEntity) : Collections.<E> emptyList();
return new PageImpl<>(content, pageable, total);
}
}
答案 2 :(得分:1)
您必须使用querydsl
并根据非null参数构建您的where
,例如
BooleanBuilder where = new BooleanBuilder();
...
if(code != null){
where.and(YOURENTITY.code.eq(code));
}
并执行查询后
JPAQuery query = new JPAQuery(entityManager).from(..)
.leftJoin( .. )
...
.where(where)
并使用您自己的页面
MaPage<YOURENTITY> page = new MaPage<YOURENTITY>();
page.number = pageNumber+1;
page.content = query.offset(pageNumber*pageSize).limit(pageSize).list(...);
page.totalResult = query.count();
我像那样创建MyPage
public class MaPage<T> {
public List<T> content;
public int number;
public Long totalResult;
public Long totalPages;
...
}
它可以工作,但如果在你的查询中你得到一个提取,那么你会有这个警告
十一月21,2014 6:48:54 AM org.hibernate.hql.internal.ast.QueryTranslatorImpl list
警告:HHH000104:使用集合提取指定的firstResult / maxResults;在记忆中应用!
它会减慢您的请求所以解决方案是获取获取并定义@BatchSize(size=10)
并使用Hibernate.initialize(....)
来获取集合和其他对象类型中的数据。
How to execute a JPAQuery with pagination using Spring Data and QueryDSL
答案 3 :(得分:0)
此处的信息已过时。让您的存储库实现QueryDslPredicateExecutor并且免费分页。