DBFlute: LikeSearchOptionのエスケープ技


DBFluteには曖昧検索のオプションを指定するオブジェクトがあります。

# MemberCB cb = new MemberCB();
# cb.query().setMemberName_LikeSearch("ス", new LikeSearchOption().likeContain());
#
# ↓
#
# select ...
# from MEMBER
# where MEMBER_NAME like '%ス%' -- 実際にはBind変数値として扱われます。

さらに、エスケープ処理もできます。

# MemberCB cb = new MemberCB();
# LikeSearchOption option = new LikeSearchOption().likeContain().escapeByPipeLine();
# cb.query().setMemberName_LikeSearch("ス", option);
#
# ↓
#
# select ...
# from MEMBER
# where MEMBER_NAME like '%ス%' escape '|' -- 実際にはBind変数値として扱われます。

外だしSQLでもエスケープ処理したいなぁと思う場合もあるかと思います。
その場合は「escape '|'」をSQLで書けば良いのですが、
「条件値のエスケープ文字列埋め込み」をプログラムでやる必要があります。
その時、LikeSearchOptionをユーティリティ的に利用することが可能です。

# final LikeSearchOption option = new LikeSearchOption();
# option.escapeByPipeLine();
# final String realValue = option.generateRealValue("abc%def_ghi");
# assertEquals("abc|%def|_ghi", realValue);

でも、せっかくなので

A. エスケープ処理があったら自動でエスケープ文字埋め込みをする
→ /*pmb.memberName*/'ス' || '%' escape '|'

B. エスケープ処理指定があったら自動でエスケープ文字埋め込みをする
→ /*#escape(|)#pmb.memberName*/'ス' || '%' escape '|'

とかもいいかもしれません。
AとBの違いは単に実現可能性の違いです。
Aの方がいいに決まっているのですがうまくできるかどうか...

【追記(2009/03/18)】
DBFlute-0.9.4からは、エスケープを明示的に指定しなくても
一致の方向が決まった時点で自動でエスケープ処理を施します。
(likePrefix()やlikeContain()を呼び出したら自動でEscape)

また、外だしSQLでもエスケープ可能です。
http://d.hatena.ne.jp/jflute/20071225/1198579979