3

1 対多の関係で Customer と Order の 2 つのエンティティがあります。顧客ごとに、関連する注文の数を数え、この数で結果を並べ替える必要があります。ネイティブの 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 を使用してクエリを作成する際の助けをいただければ幸いです。

前もって感謝します。

4

2 に答える 2

10

エンティティ 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置き換えます。CollectionJoinListJoinSetJoinMapJoin

于 2013-01-20T16:10:07.170 に答える