GORMのwithCriteriaの残念感
実際の所,ダイナミックファインダ(findByXxx系)はあまり使わず(使えず?),withCriteriaによる検索を行うことが多いのです。例えば,ダイナミックファインダは逆順(order desc)が出来ないとか,そんな簡単な理由で使いどころが限定されるのだ。
この手のCriteriaオブジェクト系のDB操作には良い思い出がないので,(SQLは早々に諦めたので)せめてHQLかなぁと思いきや,意外に抵抗なく使えた。実際使ってみると,不思議なものでHQLのほうが抵抗あったな。
#Hibernateは使ったこと無いんで,CriteriaもHSLもどっちも思い入れは無いんだけどね。
意外と便利よ,withCriteria。多分,本家はこっちなんだろうけど,createCriteriaは全然使わんかった。ただし,リファレンスの解説はcreateCriteriaのほうが充実してるんで,まずはこれ読んでおこう。
以下,残念に思うことを列挙しとく(でも,諦め付く残念さだ)。
プロパティ(検索条件)の指定が文字列だ
この 'name' って,Person.nameプロパティのことなんだよね。まあ,いいけどさ。
Person.withCriteria { friends { eq 'name', 'a1' } }
集合演算子 in が groovyの予約語とかぶっている
しょうがないから,文字列でin演算子を表す。まあ,しかたないけどさ。
Person.withCriteria { friends { 'in' 'name', ['a1', 'b2'] } }
集合関数も使えるけど,戻り値に気をつけないといけない
集約演算しても戻り値がコレクション(大抵はSet)なのは変わりない。まあ,気をつけてればいいんだけどさ。
assertEquals([2] as Set, Person.withCriteria { projections { rowCount() } friends { eq 'name', 'a1' } } as Set)
または,こう。
assertEquals(2, Person.withCriteria { projections { rowCount() } friends { eq 'name', 'a1' } }[0]) // <- ここ注目!!
それでも,withCriteriaクロージャの中で普通にGroovyの条件文を書けたり便利なところもあるので,そんなにキライではない。:-)
Person.withCriteria { friends { 'in' 'name', ['a1', 'b2'] } if (isPaging) { // isPagingが有効なら,ここも条件に加える firstResult offset maxResults 20 } }