我需要一些建议来创建一个hql查询。
情况:我已设置Nodes
,可为其分配可配置的Flags
。为此,我有以下类/表:
课程:
class Node {
String name
}
class Flag {
String name
}
class NodeHasFlag {
Node node
Flag flag
boolean value
}
包含一些示例数据的结果表:
Node
id, name
1, 'a'
2, 'b'
3, 'c'
...
Flag
id, name
1, 'visible'
2, 'special'
...
NodeHasFlag
node_id, flag_id, value
1, 1, true // node 'a' is visible
2, 1, false // node 'b' is not visible
2, 2, true // node 'b' is special
3, 1, false // node 'c' is not visible
...
现在我需要一个hql查询来获取基于标志的节点列表。
赞:向我提供visible
和special
或者:给我visible
的所有节点,special
的值未定义(NodeHasFlag
表中没有条目)
检查单个标志很容易,但同时检查多个标志会给我带来麻烦。
我正在使用Grails和Gorm,但我认为问题与标准Java Hibernate相同
答案 0 :(得分:3)
我认为你可以用子查询来解决这个问题。第一个例子看起来像这样。第二个例子需要LEFT JOIN和OR IS NULL限制。
select n from Node n
where n.id in
(select n2.id from Node n2
join n2.flags f2
where f2.visible = :visibleValue)
and n.id in
(select n3.id from Node n3
join n3.flags f3
where f3.special = :specialValue)
答案 1 :(得分:1)
你也可以发挥创意(假设NodeHasFlag永远不会有相同的node_id和flag_id)并尝试这样的事情:
// Both visible and special
select n from Node n
where 3 = (
select SUM(CASE f.name WHEN 'visible' THEN 2 WHEN 'special' THEN 1 ELSE 0 END)
from n.flags f))
或
// Visible but not special
select n from Node n
where 2 = (
select SUM(CASE f.name WHEN 'visible' THEN 2 WHEN 'special' THEN 1 ELSE 0 END)
from n.flags f))
稍微优化但不太直观:)