[英]hibernate criteria API: filtering by subset
我有一個包含一組 B 的 class。
我想制定一個 Hibernate 標准來獲取所有 A,其中 B 的集合是某個給定集合的超集。
舉個例子:
假設我們有三個 A 類型的對象
a1,它有一組 Bs = [b1, b2, b3]
a2,集合 = [b3, b4, b5]
a3, 集合 = [b3, b5]
假設我想獲得所有的 A,使其設置包含 [b3,b5]。 那么結果將是 a2 和 a3
我希望我說清楚了。 提前致謝!
曼努埃爾
我是這樣解決的。 很難弄清楚這是否有效,但是一旦您看到它就很簡單。
B[] subset = new B[] {b3, b5};
DetachedCriteria.forClass(A.class).createAlias("bs", "b");
for (B b : subset) {
criteria.add(Restrictions.eq("b.id", b.getId()));
}
我相信這個標准可以解決問題(假設A
上包含一組B
實體的屬性稱為bs
):
DetachedCriteria.forClass(A.class).add(Restrictions.and(
Restrictions.in("bs", new B[] { b3, b5 }),
Restrictions.notIn("bs", DetachedCriteria.forClass(B.class).add(
Restrictions.notIn("this", new B[] { b3, b5 }))
)
));
不過,可能效率不高。
在考慮 Criteria 之前,您需要先用鉛筆生 SQL。
您可以通過以下方式在 SQL 中執行此操作(假設有一個表AB
連接A
和B
之間的記錄,其中fk_A
指向A
中的id
, fk_B
指向B
中的id
):
SELECT fk_A, count(fk_B) FROM AB
WHERE fk_B IN (b3, b5)
GROUP BY fk_A
HAVING count(fk_B) = 2
這樣,您就不會從A
中獲得“不完整”的條目,因為HAVING count(fk_B)
語句會過濾它們。 不用說,如果 B 的數量不同,則必須將2
替換為相關數字。
接下來是將其轉換為 Criteria 的難點:) 一些偽(讀取:未經測試)代碼:
Criteria criteria = getSession().createCriteria(A.class);
criteria.add(Restrictions.in("fk_B", new String[] {b3, b5}));
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.count("fk_B"));
projectionList.add(Projections.groupProperty("fk_A"));
criteria.setProjection(projectionList);
如您所見,此 Criteria 仍然缺少HAVING
位。 不幸的是,標准 API尚不支持HAVING
。 但是,您應該獲取結果和計數列表,並忽略計數小於要求的那些。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.