hibernate criteria API:按子集过滤

时间:2011-06-05 17:53:34

标签: java hibernate criteria criteria-api

我有一个包含一组B的类。

我想制作一个Hibernate Criteria来获取所有A,其中Bs集是某个给定集的超集。

举个例子:

假设我们有三个类型为A的对象

a1,其具有Bs = [b1,b2,b3]的集合 a2,设置= [b3,b4,b5]
a3,set = [b3,b5]

假设我想得到所有的A,使得它的集合包含[b3,b5]。 然后结果将是a2和a3

我希望自己清楚明白。提前谢谢!
曼努埃尔

3 个答案:

答案 0 :(得分:1)

我这样解决了。很难弄清楚这是否有效,但一旦你看到它就很简单了。

        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()));
        }

答案 1 :(得分:0)

我相信这个标准可以解决问题(假设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 }))
    )
));

但可能效率不高。

答案 2 :(得分:0)

在考虑Criteria之前,您需要先写入原始SQL。

您可以通过以下方式在SQL中执行此操作(假设有一个表AB加入AB之间的记录,其中fk_A指向id A中的fk_Bid指向B中的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)语句过滤它们时,您不会从2获得“不完整”条目。不用说,如果Bs的数量不同,您将不得不用相关数字替换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

正如您所看到的,此标准仍然遗漏了HAVING位。不幸的是,{{1}}在Criteria API中是not yet supported。但是,您应该获得结果列表和counts,并忽略那些数量少于所需数量的结果。