- PR -

HibernateのCriteriaについて

1
投稿者投稿内容
zutto
会議室デビュー日: 2003/09/25
投稿数: 4
投稿日時: 2007-06-19 23:33
お世話になります。

商品検索画面にて商品名の部分文字列(searchString)と価格範囲(minPrice〜maxPrice)を入力し、
検索ボタンを押すと該当する商品の一覧が表示されるようにしたいと思っています。

この検索を擬似HQLで書くと次のような感じです。
コード:

select item from Item item where item.itemName like '%{searchString}%' and item.price >= {minPrice} and item.price <= {maxPrice}



動的にSQLを生成するためにHibernate(3.2.0)のCriteriaを使ってみることにしました。
そして次のようなコードを書きました。
コード:

import static org.hibernate.criterion.Restrictions.*;
... ...

//検索条件変数
String searchString;
BigInteger minPrice, maxPrice;
... ...

items = session.createCriteria(Item.class)
.add( like("itemName", searchString, MatchMode.ANYWHERE).ignoreCase() )
.add( ge("price", minPrice) )
.add( le("price", maxPrice) )
.list();


変数searchString, minPrice, maxPriceに値が設定されている場合は希望通りの結果が得られました。
ただ検索条件変数のいずれかがnullの場合は、対応する検索条件を外してくれると期待していたのですが、
HQLのログを見ると外れていません。
例えば、minPriceとmaxPriceがnullの場合、次のようなHQLを発行することを期待していました。
コード:

select item from Item item where item.itemName like '%{searchString}%'


HibernateのCriteriaはそこまでは対応してくれないのでしょうか?
それとも使い方間違っているのでしょうか?

よろしくお願いします。


[ メッセージ編集済み 編集者: zutto 編集日時 2007-06-19 23:43 ]
zutto
会議室デビュー日: 2003/09/25
投稿数: 4
投稿日時: 2007-06-20 00:22
自己レスです。

Query By Exampleではnullである検索条件を除外できるAPIがサポートされているようですが、
Criteriaでは検索条件のnullチェックはマニュアルでしないといけないみたいですね。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-06-20 10:07
コード:

items = session.createCriteria(Item.class)
.add(or(isNull(("itemName"),
like("itemName", searchString, MatchMode.ANYWHERE).ignoreCase())
.add( ge("price", minPrice) )
.add( le("price", maxPrice) )
.list();



動的にクエリーを書き換える必要がない場合は、
静的なHQLの方が(バグも少ないし)楽だと思いますよ。

Criteriaは動的に結合するテーブルを変更するとかの場合は
非常に便利なのですが、一般的にむしろ可読性が下がります。

[追記]
ついでに、
コード:

select item from Item item where item.itemName like '%{searchString}%'


これで期待通りの動きするのってOracleくらいですよ。
NULLと空文字を区別しない特殊な仕様なので。

Oracleのマニュアルにも、いつか変えるかもしれないから、
NULLと空文字が等価であることを前提としないように、って
書いてあります。いまさら変えることは無理でしょうけど。
[/追記]

[ メッセージ編集済み 編集者: あしゅ 編集日時 2007-06-20 10:20 ]
1

スキルアップ/キャリアアップ(JOB@IT)