hibernate criteria API:按子集过滤

发布于 2024-11-13 01:04:47 字数 290 浏览 2 评论 0原文

我有一个包含一组 B 的课程。

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

举个例子:

假设我们有三个 A

a1 类型的对象,它具有 Bs = [b1, b2, b3] 的集合
a2,其中集合 = [b3, b4, b5]
a3,其中 set = [b3, b5]

假设我想获取所有 A,使其集合包含 [b3,b5]。 那么结果就是a2和a3

我希望我说清楚了。预先感谢!
曼努埃尔

I have a class which contains a Set of Bs.

I'd like to make an Hibernate Criteria to get all A's for which the set of Bs is a superset of some given set.

To make an example:

let's say we have three objects of type A

a1, which has the set of Bs = [b1, b2, b3]
a2, with the set = [b3, b4, b5]
a3, with the set = [b3, b5]

suppose I want to get all A's such that it's set contains [b3,b5].
Then the result would be a2 and a3

I hope I made myself clear. Thanks in advance!
Manuel

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

丢了幸福的猪 2024-11-20 01:04:47

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

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

I solved it like this. It was hard to figure out that this worked, but It's quite simple once you see it.

        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()));
        }
毁我热情 2024-11-20 01:04:47

我相信这个标准可以解决问题(假设包含 B 实体集的 A 上的属性称为 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 }))
    )
));

可能不是很不过,效率很高。

I believe this criteria would do the trick (assuming the property on A that contains the set of B entities is called 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 }))
    )
));

Probably not very efficient, though.

℉服软 2024-11-20 01:04:47

在考虑条件之前,您需要先记下原始 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 位。不幸的是,尚不支持 HAVING标准API。但是,您应该获取结果列表和 计数 并忽略计数较少的那些比要求的。

Before thinking of Criteria, you need to pencil raw SQL first.

You could do this in SQL the following way (assuming there is a table AB joining records between A and B where fk_A points to id in A and fk_B points to id in B):

SELECT fk_A, count(fk_B) FROM AB
   WHERE fk_B IN (b3, b5)
   GROUP BY fk_A 
   HAVING count(fk_B) = 2

This way you will not get "incomplete" entries from A as HAVING count(fk_B) statement filters them. Needless to say, you will have to replace 2 with relevant number if the amount of Bs is different.

Next goes the hard bit of converting this into Criteria :) Some pseudo (read: untested) code:

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

As you can see, this Criteria still misses HAVING bit in it. Unfortunately, HAVING is not yet supported in Criteria API. You should, however, get the list of results and counts and ignore those where count is less than required.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文