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