LikeSearch
- 概要
- 実装方法
- 一致の方向の指定
- 区切り文字でスプリットして複数条件
- メソッド仕様
- サポートされる型
- 前方一致:PrefixSearch @until 1.0.x
- 否定条件:NotLikeSearch
概要
基本概念
曖昧検索の条件(like)を設定します。LikeSearch は、絞り込み条件を表す ConditionKey です。
オプションを指定することで、部分一致、前方一致など、曖昧検索の汎用的な条件を指定することができます。 また、エスケープ処理の自動解決など、曖昧検索に関わる支援機能を備えます。
会話上では、らいくさーち と表現します。
実装方法
実装の流れ ※1.1.x (Java8版)
query() の後、set[column-name]_LikeSearch() を呼び出し、第一引数に条件値、第二引数に LikeSearchOption を指定します。
e.g. LikeSearch条件の実装手順 (Eclipseでコード補完) {MEMBER_NAME} @Java
MemberCB cb = new MemberCB();
cb.q // .q と打って enter
--
cb.query()
--
// .set まで打つとカラム選択
// MN (MemberName) でカラム確定、LS (LikeSearch) で enter
cb.query().setMNLS
--
// 第一引数の "memberName" が選択状態に
cb.query().setMemberName_LikeSearch(memberName, opLambda);
--
// 第一引数に検索条件の値を指定して...
cb.query().setMemberName_LikeSearch("S", opLambda);
--
// tab を一回押して、第二引数の方を "opLambda" を選択状態に
// そして、_li で補完 (DBFlute補完テンプレートが有効なら)
cb.query().setMemberName_LikeSearch("S", _li);
--
// Lambda引数名は op (option) に、前方一致か部分一致かあいまい検索のオプションを
cb.query().setMemberName_LikeSearch("S", op -> op.likePrefix());
実装の流れ ※1.0.x (Java6版)
e.g. LikeSearch条件の実装手順 (Eclipseでコード補完) {MEMBER_NAME} @Java
MemberCB cb = new MemberCB();
cb.q // .q と打って enter
--
cb.query()
--
// 1. .set まで打つとカラム選択
// 2. MN (MemberName) でカラム確定
// 3. LS (LikeSearch) で enter
cb.query().setMNLS
--
cb.query().setMemberName_LikeSearch(memberName, option);
--
cb.query().setMemberName_LikeSearch("S"
, new LikeSearchOption().likePrefix()); // "S" で始まる会員
一致の方向の指定
like[direction]()メソッド
LikeSearchOption の like[direction]()メソッドを呼び出すことで指定します。
- likePrefix()
- 前方一致
- likeContain()
- 部分一致
- likeSuffix()
- 後方一致
一致方向が指定された場合は、条件値の中にワイルドカードを含める必要はありません。内部的に一致の方向を踏まえてワイルドカードを付与します。
エスケープ処理の自動解決
同時にエスケープ処理は自動解決されます。 SQLではエスケープ句が付与され、かつ、指定された条件値の中にエスケープ対象(ワイルドカードとエスケープ文字自体)の文字があった場合は、 エスケープ文字で内部的にエスケープされます(エスケープ文字はデフォルトでパイプライン "|" です)。
e.g. 部分一致で条件値にエスケープ文字が含まれている @Java
cb.query().setMemberName_LikeSearch("100%Juice", op -> op.likeContain());
e.g. 部分一致で条件値のエスケープ文字をエスケープ @DisplaySql
...
where MEMBER_NAME like '%100|%Juice%' escape '|'
エスケープ対象のワイルドカードは、全角のものも含まれます(例えば、全角の "%")。全角もワイルドカードとして扱うDBMSがあるためです。 全角がワイルドカードにならないDBMSでも、そのエスケープ文字は単に無視されるだけですので動作に影響はありません。 少なくとも、DBFluteがサポートしているDBMSにおいてはテストで確認がされています。
条件値にワイルドカードを含める
一致の方向を条件値に含まれたワイルドカードで表現する場合は、likeXxx() メソッドを呼び出さずに指定します。その場合、エスケープ処理もされません。
区切り文字でスプリットして複数条件
例えば、条件値が "SEA LAND PIARI" と空白区切りになっていて、"SEA" を含む、かつ、"LAND" を含む、かつ、"PIARI" を含む、というような複数条件の曖昧検索をしたい場合、この空白区切りを内部的に分解して自動的に複数条件として扱う機能があります。
- AND 条件
- splitBySpace()
- OR 条件
- splitBySpace().asOrSplit()
e.g. 空白区切りでスプリット (AND条件) @Java
MemberCB cb = new MemberCB();
cb.query().setMemberName_LikeSearch("SEA LAND PIARI"
, op -> op.likeContain().splitBySpace());
e.g. 空白区切りでスプリット (AND条件) @DisplaySql
...
where MEMBER_NAME like '%SEA%' escape '|'
and MEMBER_NAME like '%LAND%' escape '|'
and MEMBER_NAME like '%PIARI%' escape '|'
e.g. 空白区切りでスプリット (OR条件) @Java
MemberCB cb = new MemberCB();
cb.query().setMemberName_LikeSearch("SEA LAND PIARI"
, op -> op.likeContain().splitBySpace().asOrSplit());
e.g. 空白区切りでスプリット (OR条件) @DisplaySql
...
where (MEMBER_NAME like '%SEA%' escape '|'
or MEMBER_NAME like '%LAND%' escape '|'
or MEMBER_NAME like '%PIARI%' escape '|')
デリミタの調整
デリミタ(区切り文字)の調整がメソッドで用意されています。 特に空白に近いもの、例えば、全角空白やタブ、改行など、 業務的にどのように扱うのかしっかりアプリでの要件(もしくは、ポリシー)を明確にした上でメソッドを選んで下さい。
- splitByBlank() @since 0.9.7.5
- 半角空白・全角空白・タブ・改行で区切る。
- 大抵のケースは、このメソッドで問題なく、利用頻度の一番高いものと想定される。
- splitBySpace()
- 純粋に半角空白だけで区切る。
- 全角空白など別の値を業務的な値として利用する場面が想定される。
- splitBySpaceContainsDoubleByte()
- 半角空白に加えて、全角空白でも区切る。タブや改行は対象外。
- splitByPipeLine()
- パイプライン "|" で区切る
- splitByVarious(List delimiterList) @since 0.9.7.5
- 指定された値で区切る。もし、別の箇所でも同じ区切り文字を指定する場合は、LikeSearchOption の継承クラスをアプリ独自に作成し、デリミタの指定を再利用することが推奨される。
Split のリミット指定
また、それぞれのメソッドがオーバーロードで "int splitLimitCount" という引数を受け取れるようになっています。 例えば、"幾つ区切り文字があっても最大で 5 つまでの条件しか作らない" というような仕様があった場合に、splitLimitCount に 5 を指定します。この場合 6 つ目以降の要素は無視されます。
メソッド仕様
基本仕様
以下項目、全て Equal と同じ仕様となります。
- nullや空文字の指定
- 大文字小文字の区別
- char型でサイズ不足の値
同カラムに対する複数条件の指定
追加条件となります。(指定した分だけ条件になる)
同カラムに対する同じ条件値での複数指定
追加条件となります。(指定した分だけ条件になる)
指定されたオプションの再利用
LikeSearchOption はスレッドセーフではありませんが、同じスレッド内であれば別のカラムに再利用することはできます。 全く同じオプションで、別のカラムも曖昧検索する場合に利用できます。
サポートされる型
String 型のみです。
前方一致:PrefixSearch @until 1.0.x
※こちら、1.1.x (Java8版) からはデフォルトで自動生成されなくなりました。LikeSearch で likePrefix() を使うようにしてください。
業務的に頻度の高いと思われる前方一致に関しては PrefixSearch という ConditionKey として独立したメソッドで提供されています(LikeSearchOptionの指定不要)。内部的には LikeSearch を使って、LikeSearchOption.likePrefix() を指定しています。
e.g. PrefixSearch @Java
cb.query().setMemberName_PrefixSearch("100%Juice");
否定条件:NotLikeSearch
否定条件の曖昧検索として、NotLikeSearch もあります。条件が否定になっただけで仕様は LikeSearch と全く同じです。
e.g. NotLikeSearch @Java
cb.query().setMemberName_NotLikeSearch("100%Juice", op -> op.likeContain());