【问题标题】:Selecting collections in HQL在 HQL 中选择集合
【发布时间】:2013-03-04 20:36:30
【问题描述】:

HQL 菜鸟在这里,真的很挣扎。

假设我有以下三个类:

public class A {
int id;
B b;
}

public class B {
int id;
Set<C> c;
}

public class C {
int id;
String type;
}

表 B 与 C 具有多对多关系,由表 b_c 定义。我需要一个查询,从表 A 中选择,按 C.id 分组,按 C.type = 'desiredType' 过滤,并返回 C 对象和 A.id 的计数。我一直在玩类似的东西:

SELECT c, COUNT(a.id) as count from A a JOIN a.b.c as c WHERE c.type = 'desiredType' GROUP BY c.id ORDER BY COUNT(a.id) desc

我已经尝试过这个查询的不同迭代,但我不断收到各种异常,否则我的查询将什么也不返回。我似乎不理解的主要问题是如何返回与正确类型匹配的集合的各个对象。

我希望这个问题听起来不是很愚蠢。我已经阅读了 HQL 手册和其他一百个 SO 问题,但我一定遗漏了一些东西。提前感谢您的任何指导。

【问题讨论】:

  • 不是对您的问题的直接回答,但问题是您最好执行更严格的 oop,而不是在您的对象 C 上使用 type 您将添加该类的子类型使用数据库的列类型作为判别式。那么只请求正确类型的 C 会更容易。另一方面,我忍受着请求过滤集合休眠的痛苦。

标签: hibernate collections hql


【解决方案1】:

你想做的事情不会以这种方式工作。最后,您想从 A 和 B 中进行选择,但只选择适合您条件的 B.c 的一个子集。这是不可能的。 Hibernate 只能加载完整的集合 c(不是 100% 正确,您可以限制映射中的选择,但这不是这里的解决方案)。这样就有可能无法满足您的要求。您加载所有受 exists 子句限制的 A 并手动计数:

FROM A a where EXISTS (SELECT 1 FROM C, B_C
                          WHERE C.type = 'desiredType'
                             AND B_C.c_id = C.id
                             AND B_C.b_id = a.b.id)

然后你必须循环遍历列表的所有元素,这些元素是 A 的实例,检查所有 a.b.c 的内部循环是否 C 是所需的类型(仍然必须完成;上select 仅将选择限制为具有至少一个所需类型的 C 的 A,但在您的列表中,您拥有这些 A 的所有 C)并设置正确 c.id 的计数。

该解决方案的缺点是,即使类型错误,也会加载所有 C,并且所有计数都必须在 Java 代码中完成。所以你可能不喜欢那个解决方案。

更好的解决方案是:

从表 C 开始思考。在类 C 中添加Set &lt;B&gt; b;(它是多对多关系;将连接表 B_C 定义为 Java 类可能更方便)。在 B 类中,您添加对表 A 的访问,或者添加 A a(如果 B:A 是 1:1 关系)或 Set&lt;A&gt; a(如果 B:A 是 1:n 关系)。然后你只需选择所需的 C:

FROM C WHERE C.type = 'desiredType'

A group by C.id 您刚刚在 Java 中通过 countA = c.b.size()(A 和 B 之间的 1:1 关系)或 countA = 0; for (B b : c.b) {countA += b.a.size()}(A 和 B 之间的 n:1 关系)获得的每个选定 c 的计数。

【讨论】:

    猜你喜欢
    • 2017-01-22
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 2011-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多