簡體   English   中英

hibernate 標准 API:按子集過濾

[英]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連接AB之間的記錄,其中fk_A指向A中的idfk_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.

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