Java hibernate标准API:按子集筛选
我有一个包含一组B的类 我想建立一个Hibernate标准来获取所有A,对于这些A,B的集合是某个给定集合的超集 举个例子: 假设我们有三个类型为A的对象 a1,其具有Bs=[b1、b2、b3]的集合Java hibernate标准API:按子集筛选,java,hibernate,criteria,criteria-api,Java,Hibernate,Criteria,Criteria Api,我有一个包含一组B的类 我想建立一个Hibernate标准来获取所有A,对于这些A,B的集合是某个给定集合的超集 举个例子: 假设我们有三个类型为A的对象 a1,其具有Bs=[b1、b2、b3]的集合 a2,带集合=[b3,b4,b5] a3,带集合=[b3,b5] 假设我想得到所有的A,使得它的集合包含[b3,b5]。 那么结果将是a2和a3 我希望我说清楚了。提前谢谢 Manuel我相信这个标准会奏效(假设A上包含B实体集的属性称为bs): 不过,效率可能不是很高。在考虑标准之前,您需要先编
a2,带集合=[b3,b4,b5]
a3,带集合=[b3,b5] 假设我想得到所有的A,使得它的集合包含[b3,b5]。 那么结果将是a2和a3 我希望我说清楚了。提前谢谢
Manuel我相信这个标准会奏效(假设
A
上包含B
实体集的属性称为bs
):
不过,效率可能不是很高。在考虑标准之前,您需要先编写原始SQL 您可以通过以下方式在SQL中执行此操作(假设在
a
和B
之间有一个表AB
连接记录,其中fk_a
在a
中指向id
,而fk_B
在B
中指向id
):
这样,您就不会从A
中获得“不完整”的条目,因为HAVING count(fk_B)
语句会过滤它们。不用说,如果Bs的数量不同,您将不得不用相关编号替换2
接下来是将其转换为标准的难点:)一些伪(读:未测试)代码:
正如您所看到的,此标准仍然缺少包含位的
。不幸的是,具有
在标准API中。但是,您应该获得结果列表,忽略那些计数低于要求的结果。我这样解决了这个问题。很难看出这是否有效,但一旦你看到它,它就相当简单了
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()));
}
这不管用。在本例中,它还将返回a1,因为a1在{b3,b5}.aha中有一个'b'。很抱歉错过了那个细节。看看我刚才的编辑。我不确定“this”是否适用于条件查询(我一时想不起来),但如果不适用,则可以使用实体的id。
SELECT fk_A, count(fk_B) FROM AB
WHERE fk_B IN (b3, b5)
GROUP BY fk_A
HAVING count(fk_B) = 2
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);
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()));
}