簡體   English   中英

JPA CriteriaBuilder - 按一對多關系中關聯實體的數量排序

[英]JPA CriteriaBuilder - sort by the number of associated entities in a one-to-many relationship

我有兩個實體 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<Order> orders;

您可以使用以下查詢:

EntityManager em;  // to be built or injected
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<Customer> customer = cq.from(Customer.class);
CollectionJoin<Customer, Order> 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<Tuple> 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替換為正確類型的集合( ListJoinSetJoinMapJoin )。

在規范中使用它

cq.orderBy(cb.desc(cb.count(orders)));

同時發送PageRequest(1, 10, Sort.unsorted()) 我就是這樣做的。 如果您將 Sort 值作為 unsorted 傳遞,然后使用您自己的對加入的實體進行排序的邏輯覆蓋標准查詢

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM