2012-05-04 9 views
3

Grails/Hibernateの "すべての"条件クエリを実行する方法が必要です。標準の「in」制限は、「in any」制限と呼ぶものです。一例としてGrails/Hibernate Criteriaクエリの "all in"制限

...

前文

別のドメインクラス「危険」との多対多関連を持っている「騎士」ドメインクラスを取ります。クラスは...単純です、私は協会に検索するチェックボックスを提供していますフォームを提示

 
    Knights 
    1 Arthur, King of the Britains (Not technically a knight. I know, I know.) 
    2 Sir Bedevere the Wise 
    3 Sir Lancelot the Brave 
    4 Sir Robin the Not-Quite-So-Brave-As-Sir-Lancelot 
    5 Sir Galahad the Pure 

    Perils 
    1 Black Knight 
    2 Knights who say Ni 
    3 Three-Headed Giant 
    4 Swamp Castle 
    5 Castle Anthrax 
    6 Rabbit of Caerbannog 

    Knights_Perils 
    1, 1  // arthur fights the black knight 
    1, 2  // arthur fights the knights who say ni 
    2, 2  // bedevere fights the knights who say ni 
    4, 3  // Robin runs-away from Three-Headed Giant 
    3, 4  // Lancelot Assaults Swamp Castle 
    5, 5  // Galahad visits Castle Anthrax 
    3, 5  // Lancelot "rescues" Galahad from Castle Anthrax 
    1, 6  // All Knights fight the Killer Bunny 
    2, 6  // ... 
    3, 6  // ... 
    4, 6  // ... 
    5, 6  // ... 

class Knight { 
    String name 
    static hasMany = [perils:Peril] 
} 

class Peril { 
    String name 
    static hasMany = [knights:Knight] 
    static belongsTo = Knight 
} 

テーブルの内容は、次のようになります... ...

 
    Choose Perils and Search for Knights... 
    [ ] Black Knight (id 1) 
    [ ] Knights who say Ni (id 2) 
    [ ] Three-Headed Giant (id 3) 
    [x] Swamp Castle (id 4) 
    [x] Castle Anthrax (id 5) 
    [x] Killer Bunny (id 6) 

    [search] 

これは次のようにクエリします:

def query = Knights.createQuery() 
query.list(max: params.max, offset: params.offset) { 
    if(params.perils) perils { 'in' ('id', params.list('perils')*.toLong()) } 
} 

これは、私が「すべての」結果と呼ぶものをもたらします。ナイトは、チェックされた危険のリストの中の「どれでも」の関連付けをしています。 3の場合は、上記のフォームで、私は「中」に似休止/ Grailsの基準制限を探していますすべての騎士...

 
    Arthur - fights bunny 
    Bedevere - fights bunny 
    Lancelot - swamp castle, castle anthrax, fights bunny 
    Robin - fights bunny 
    Galahad - castle anthrax, fights bunny 

質問

を危険にチェックしかし、それは "すべてで"照会するでしょう。言い換えれば、騎士団はリスト内のチェックされた危険の「すべて」に関連しています。この制限、および上記と同じフォーム入力で、私は結果だけ

 
    Lancelot - swamp castle, castle anthrax, fights bunny 

ことを期待するHibernateの基準のバージョン「すべての」制限「の」ありますか?

私は、CriteriaQuery(HibernateまたはGrailsのいずれかの方言)でこれを実行したいと思います。直接SQLまたはHQLではありません。

これに対処する方法の指針はありますか?

ありがとうございました!

  • ゲイリー

答えて

1

良い質問。たぶんそこに私は、SQL/HQLのあらゆる側面を知っていないので、良いオプションは、ですが、次の句:

all the selected perils are in the knight's perils 

もHQLで、だから、この

there is no peril in the selected perils that is not in the knight's perils 

のように表現することができ、あなた次のように表現できます:

select knight from Knight knight 
where not exists (select peril.id from Peril peril 
        where peril.id in :selectedPerilIds 
        and peril.id not in (select peril2.id from Peril peril2 
             where peril2.knight.id = knight.id))