JPA CriteriaBuilder – 按一对多关系中的关联实体数量排序
我有两个实体Customer和Order,一对多关系。 对于每个客户,我需要计算相关订单的数量,并按此数字对结果进行排序。 在本机postgres查询中,它看起来像这样:
select cust.id, count(order.id) from customers cust left outer join orders order on cust.id = order.customer_id where .... conditions ... group by cust.id order by count desc;
但我必须使用CriteriaBuilder执行此操作,因为此查询是使用CriteriaBuilder添加其他条件的更大代码段的一部分。 在Hibernate中我可能会使用Projections,但我在JPA中找不到类似的东西。
任何使用CriteraBuilder编写查询的帮助都将非常感激。
先谢谢你。
假设实体Customer有这样的OneToMany
属性:
@OneToMany(mappedBy = "customerId") private Collection orders;
您可以使用以下查询:
EntityManager em; // to be built or injected CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createTupleQuery(); Root customer = cq.from(Customer.class); CollectionJoin orders = customer.join(Customer_.orders, JoinType.LEFT); cq.select(cb.tuple(customer, cb.count(orders))); cq.where(... add some predicates here ...); cq.groupBy(customer.get(Customer_.id)); cq.orderBy(cb.desc(cb.count(orders))); List result = em.createQuery(cq).getResultList(); for (Tuple t : result) { Customer c = (Customer) t.get(0); Long cnt = (Long) t.get(1); System.out.println("Customer " + c.getName() + " has " + cnt + " orders"); }
上述方法使用Metamodel 。 如果您不喜欢它,可以将Customer_.orders
替换为"orders"
,将Customer_.id
替换为"id"
。
如果OneToMany
属性是另一种类型,则将CollectionJoin
替换为正确类型的集合( ListJoin
, SetJoin
, MapJoin
)。