0

我需要一些关于创建 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 相同

4

2 回答 2

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)
于 2013-05-01T19:57:40.830 回答
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))

更优化但不太直观:)

于 2013-05-01T20:35:13.080 回答