【问题标题】:Querying a many to many join table with HQL使用 HQL 查询多对多连接表
【发布时间】:2013-05-01 12:38:31
【问题描述】:

我需要一些关于创建 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 查询来获取基于标志的节点列表。

赞:给我visiblespecial的所有节点

或者:给我所有 visible 并且具有未定义的 special 值的节点(NodeHasFlag 表中没有条目)

检查单个标志很容易,但同时检查多个标志给我带来了麻烦。

我正在使用 Grails 和 Gorm,但我认为问题与标准 Java Hibernate 相同

【问题讨论】:

  • 问题是 HQL 不支持相交或联合。您可以执行每个 HQL 语句,然后与列表相交。

标签: sql hibernate grails hql grails-orm


【解决方案1】:

我认为您可以使用子查询来解决这个问题。第一个示例可能如下所示。第二个示例需要 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)

【讨论】:

  • 谢谢。我认为这对我有帮助:-)
【解决方案2】:

您也可以发挥创意(假设 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))

更优化但不太直观:)

【讨论】:

  • 感谢这个想法,但我认为 carbontax 的方法更可靠。
  • @Jim Sosa - 我个人对这种创造性方法有一个弱点,但它们很少能在现实生活中向您的应用程序抛出的情况下生存下来。尽管如此,它还是很诱人。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2020-03-26
  • 2012-08-24
  • 1970-01-01
  • 2018-01-26
  • 2011-08-21
相关资源
最近更新 更多