繁体   English   中英

hibernate 标准 API:按子集过滤

[英]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连接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位。 不幸的是,标准 API尚不支持HAVING 但是,您应该获取结果和计数列表,并忽略计数小于要求的那些。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM