Java JPA CriteriaQuery实现Spring数据分页。getSort()
我使用JPA CriteriaQuery构建了我的动态查询,并传入了一个Spring数据分页对象:Java JPA CriteriaQuery实现Spring数据分页。getSort(),java,spring,hibernate,spring-data-jpa,jpa-criteria,Java,Spring,Hibernate,Spring Data Jpa,Jpa Criteria,我使用JPA CriteriaQuery构建了我的动态查询,并传入了一个Spring数据分页对象: sort=name,desc 在后端,我的存储库中有一个支持动态查询的方法: public Page<User> findByCriteria(String username, Pageable page) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<User> cq = cb
sort=name,desc
在后端,我的存储库中有一个支持动态查询的方法:
public Page<User> findByCriteria(String username, Pageable page) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> iRoot = cq.from(User.class);
List<Predicate> predicates = new ArrayList<Predicate>();
if (StringUtils.isNotEmpty(username)) {
predicates.add(cb.like(cb.lower(iRoot.<String>get("username")), "%" + username.toLowerCase() + "%"));
}
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
cq.where(predArray);
TypedQuery<User> query = em.createQuery(cq);
int totalRows = query.getResultList().size();
query.setFirstResult(page.getPageNumber() * page.getPageSize());
query.setMaxResults(page.getPageSize());
Page<User> result = new PageImpl<User>(query.getResultList(), page, totalRows);
return result;
}
公共页面findByCriteria(字符串用户名,可分页页面){
CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(User.class);
Root-iRoot=cq.from(User.class);
列表谓词=新的ArrayList();
if(StringUtils.isNotEmpty(用户名)){
add(cb.like(cb.lower(iRoot.get(“username”),“%”加username.toLowerCase()+“%”);
}
谓词[]predArray=新谓词[predicates.size()];
toArray(predArray);
cq.where(pred数组);
TypedQuery=em.createQuery(cq);
int totalRows=query.getResultList().size();
query.setFirstResult(page.getPageNumber()*page.getPageSize());
query.setMaxResults(page.getPageSize());
PageResult=newPageImpl(query.getResultList(),Page,totalRows);
返回结果;
}
注意:为了演示,我只放了一个参数
然而,返回的数据是未排序的,因此我想问的是,在CriteriaQuery中实现分页的任何方法。在您的CriteriaQuery中,我看不到排序信息 我会这样写:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> iRoot = cq.from(User.class);
List<Predicate> predicates = new ArrayList<Predicate>();
if (StringUtils.isNotEmpty(username)) {
predicates.add(cb.like(cb.lower(iRoot.<String>get("username")), "%" + username.toLowerCase() + "%"));
}
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
cq.where(predArray);
List<Order> orders = new ArrayList<Order>(2);
orders.add(cb.asc(iRoot.get("name")));
orders.add(cb.asc(iRoot.get("desc")));
cq.orderBy(orders);
TypedQuery<User> query = em.createQuery(cq);
Page<User> result = new PageImpl<User>(query.getResultList(), page, totalRows);
return result;
CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(User.class);
Root-iRoot=cq.from(User.class);
列表谓词=新的ArrayList();
if(StringUtils.isNotEmpty(用户名)){
add(cb.like(cb.lower(iRoot.get(“username”),“%”加username.toLowerCase()+“%”);
}
谓词[]predArray=新谓词[predicates.size()];
toArray(predArray);
cq.where(pred数组);
列表顺序=新的ArrayList(2);
orders.add(cb.asc(iRoot.get(“name”));
orders.add(cb.asc(iRoot.get(“desc”));
cq.订购人(订单);
TypedQuery=em.createQuery(cq);
PageResult=newPageImpl(query.getResultList(),Page,totalRows);
返回结果;
我没有测试它,但它应该可以工作
Angelo您可以使用spring中的QueryTils添加排序:
query.orderBy(QueryUtils.toOrders(pageable.getSort(),root,builder))代码>CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(User.class);
Root-iRoot=cq.from(User.class);
列表谓词=新的ArrayList();
if(StringUtils.isNotEmpty(用户名)){
add(cb.like(cb.lower(iRoot.get(“username”)),“%”+
username.toLowerCase()+“%”);
}
谓词[]predArray=新谓词[predicates.size()];
toArray(predArray);
cq.where(pred数组);
cq.orderBy(cb.desc(user.get(“name”));
TypedQuery=em.createQuery(cq);
PageResult=newPageImpl(query.getResultList(),Page,totalRows);
返回结果;
但如何使其动态化?它是在您的代码中硬编码的,我想Pageable会自动排序?Pageable不会自动排序;它必须是执行此操作时的查询。如果您希望友好地使用它,您应该将顺序(或等效的DTO)传递给findByCriteria paramsThanks方法,我已经找到了一个解决方案,通过使用Pageable、getSort()手动执行排序。@Javatar我很好奇您是如何成功地使用Pageable.getSort()来执行动态操作的。我尝试了cq.where(cb.and(谓词)).orderBy(pageable.getSort().stream().collect(Collectors.toList())代码>其中cq是我的标准查询。它无法工作,因为Pageable中的Orders列表是一个springframework对象,CriteriaQuery API正在等待一个Hibernate对象:((编辑:好的,我再次读了你的评论,你说“手动”nvm)Spring speak中的两个值字符串“name,desc”表示“按名称降序排序”。上面的代码尝试对名为“desc”的列进行排序我认为这会破坏。获取完整的结果集只是获取其大小似乎是浪费-传输所有数据并丢弃它。相反,应该在JPA中调用什么方法来告诉查询只获取计数?什么是生成器?@ThxXth它是CriteriaBuilder。
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> iRoot = cq.from(User.class);
List<Predicate> predicates = new ArrayList<Predicate>();
if (StringUtils.isNotEmpty(username)) {
predicates.add(cb.like(cb.lower(iRoot.<String>get("username")), "%" +
username.toLowerCase() + "%"));
}
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
cq.where(predArray);
cq.orderBy(cb.desc(user.get("name")));
TypedQuery<User> query = em.createQuery(cq);
Page<User> result = new PageImpl<User>(query.getResultList(), page, totalRows);
return result;