JPA Criteria查询API和按两个列排序

69

我遇到了一个简单的问题,不知道如何在联接的实体上调用order by。本质上,我正在尝试使用JPA Criteria实现以下内容:

select distinct d from Department d 
left join fetch d.children c 
left join fetch c.appointments a
where d.parent is null 
order by d.name, c.name

我有以下内容:

CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Department> c = cb.createQuery(Department.class);
Root<Department> root = c.from(Department.class);
Fetch<Department, Department> childrenFetch = root.fetch(
    Department_.children, JoinType.LEFT);
childrenFetch.fetch(Department_.appointments, JoinType.LEFT);

c.orderBy(cb.asc(root.get(Department_.name)));
c.distinct(true);
c.select(root);
c.where(cb.isNull(root.get(Department_.parent)));

如何使用 Criteria API 实现 order by d.name, c.name?我尝试使用 ExpressionPath,但没有成功。 非常感谢您提供任何指示。

5个回答

100

如果您需要添加一些订单,您可以进行类似的操作(但是针对您的查询和不同的根对象)。

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Route> query = criteriaBuilder.createQuery(Route.class);
Root<Route> routeRoot = query.from(Route.class);
query.select(routeRoot);

List<Order> orderList = new ArrayList();
query.where(routeRoot.get("owner").in(user));

orderList.add(criteriaBuilder.desc(routeRoot.get("date")));
orderList.add(criteriaBuilder.desc(routeRoot.get("rating")));

query.orderBy(orderList);

20

我在使用Criteria API时遇到了与“order by”相关的问题,我找到了以下解决方案:

CriteriaQuery<Test> q = cb.createQuery(Test.class);
Root<Test> c = q.from(Test.class);
q.select(c);
q.orderBy(cb.asc(c.get("name")), cb.desc(c.get("prenom")));

9
我之前遇到了同样的问题,后来在这个页面找到了解决方案: http://www.objectdb.com/api/java/jpa/criteria/CriteriaQuery/orderBy_Order_
//javax.persistence.criteria.CriteriaQuery
//CriteriaQuery<T> orderBy(Order... o)

指定用于排序查询结果的排序表达式。如果有先前的排序表达式,将替换它们。如果没有指定排序表达式,则先前的排序(如果有)将被删除,并且结果将以任意顺序返回。排序表达式的从左到右的顺序决定了优先级,最左边的具有最高的优先级。
参数: o - 零个或多个排序表达式
返回值: 修改后的查询
自: JPA 2.0

1
这怎么成为作者所描述的问题的答案了? - ByeBye
2
你为什么认为它不行?他想知道如何按多个属性排序。我的回答包含了如何做到这点……我漏掉了什么吗? - Adamsan
因为它无法与连接表的属性去重和排序一起使用。 - ByeBye

0

对我有效的解决方案如下:

session=HibernateUtil.getSessionJavaConfigFactory_report().openSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Object[]> criteriaQuery = builder.createQuery(Object[].class);
List<Order> orderList = new ArrayList();
orderList.add(builder.desc(ejeRoot.get("name")));
criteriaQuery.orderBy(orderList);

注意:ejeRoot是类对象。

0

categoryRepository.findAll(predicates, new Sort(Direction.ASC, "sortOrder", "name")) .forEach(categoryDtoList::add);

categoryRepository.findAll(predicates, new Sort(Direction.ASC, "sortOrder", "name")) .forEach(categoryDtoList::add);


这可以用来根据sortOrder和名称对列表进行排序,如果sortOrder相同,则根据名称对元素进行排序。 - pradeep
这仅适用于Spring Data用户。 - Marcel Overdijk

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