2013-05-01 140 views
0

我需要一些建議來創建一個hql查詢。查詢與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和格姆,但我認爲這個問題將與標準的Java休眠

+0

問題是HQL不支持相交或聯合。你可以做每個HQL語句,然後交叉列表。 – 2013-05-01 13:11:51

回答

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) 
+0

謝謝。我認爲這可以幫助我:-) – micha 2013-05-03 18:39:53

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)) 

多一點優化,但少直觀:)

+0

感謝這個想法,但我認爲carbontax的approuch更可靠。 – micha 2013-05-03 18:42:46

+0

@Jim Sosa - 我個人對於這種創造性的方法有一個弱點,但是他們很難在現實生活中會對你的應用產生影響的情況下倖存下來。儘管如此,它很誘人。 :) – carbontax 2013-05-03 21:00:19