我有一个包含一组B的类。
我想制作一个Hibernate Criteria来获取所有A,其中Bs集是某个给定集的超集。
举个例子:
假设我们有三个类型为A的对象
a1,其具有Bs = [b1,b2,b3]的集合
a2,设置= [b3,b4,b5]
a3,set = [b3,b5]
假设我想得到所有的A,使得它的集合包含[b3,b5]。 然后结果将是a2和a3
我希望自己清楚明白。提前谢谢!
曼努埃尔
答案 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
加入A
和B
之间的记录,其中fk_A
指向id
A
中的fk_B
和id
指向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,并忽略那些数量少于所需数量的结果。