I used JPA CriteriaQuery to build my dynamic Query and pass in a Spring Data Pageable object:
sort=name,desc
At the backend I have a method in my Repository to support dynamic query:
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;
}
Note: I put only one param for demo purpose.
However the returned data is unsorted therefore I would like to ask is that any way to implement Pageable in CriteriaQuery.
In Spring Data, if we need to return a few results from the complete data set, we can use any Pageable repository method, as it will always return a Page. The results will be returned based on the page number, page size, and sorting direction.
The simplest way to implement pagination is to use the Java Query Language – create a query and configure it via setMaxResults and setFirstResult: Query query = entityManager. createQuery("From Foo"); int pageNumber = 1; int pageSize = 10; query.
The Pageable implementation represents a set of pages to be printed. The Pageable object returns the total number of pages in the set as well as the PageFormat and Printable for a specified page.
Adjective. pageable (not comparable) That can be paged. (computer science, of computer memory) That accepts paging.
You can add sorting using QueryUtils from spring:
query.orderBy(QueryUtils.toOrders(pageable.getSort(), root, builder));
In your criteria query i see no sort information I'd write in this way:
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;
I didn't test it but it should work
Angelo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With