[英]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.