データベースでLIKE検索を行う際、検索対象の文字列に%や_といった特殊文字が含まれている場合、適切なエスケープ処理が必要になります。この記事では、MyBatisを使ったLIKE検索の際の特殊文字のエスケープ方法について解説します。
LIKEクエリでの特殊文字の扱い
SQLのLIKE句では、%はワイルドカード文字として、は任意の文字として扱われます。 そのため、検索対象の文字列に%が含まれていると、本来の検索意図と異なる結果が返される可能性があります。
例えば、商品名に”A%B”が含まれる商品を検索したい場合、%はワイルドカードとして扱われてしまい、”ABCD”や”A123B”なども検索結果に含まれてしまいます。
そこで、LIKEクエリを使う際は、検索対象の文字列に含まれる特殊文字をエスケープする必要があります。
LikeUtilsクラスによるエスケープ処理
エスケープ処理を行うためにLikeUtilsを作成しました。
package util;
public class LikeUtils {
/**
* 文字列をLIKEクエリ用にエスケープし、前後に%を付加する
*/
public static String escapeForLikeContains(String str) {
if (str == null) {
return null;
}
return "%" + escapeForLike(str) + "%";
}
/**
* 文字列をLIKEクエリ用にエスケープし、後ろに%を付加する
*/
public static String escapeForLikeStartsWith(String str) {
if (str == null) {
return null;
}
return escapeForLike(str) + "%";
}
/**
* 文字列をLIKEクエリ用にエスケープし、前に%を付加する
*/
public static String escapeForLikeEndsWith(String str) {
if (str == null) {
return null;
}
return "%" + escapeForLike(str);
}
/**
* 文字列をLIKEクエリ用にエスケープする
*/
private static String escapeForLike(String str) {
return str.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_");
}
}
LikeUtilsには、前方一致、後方一致、部分一致の各パターンに対応したメソッドが用意されています。 これらのメソッドを使うことで、MyBatisのクエリ定義で特殊文字のエスケープ処理を簡単に行えるようになります。
<select id="searchProductsByNamePrefix" parameterType="string" resultType="Product">
<bind name="namePrefix" value="@util.LikeUtils@escapeForLikeStartsWith(name)" />
SELECT * FROM products WHERE name LIKE #{namePrefix}
</select>
まとめ
MyBatisを使ったLIKE検索の際は、検索対象の文字列に含まれる%や_といった特殊文字をエスケープする必要があります。
この記事では、MyBatisでLIKE検索を行う際のエスケープ方法と、LikeUtilsクラスによる共通化について解説しました。
LIKEクエリを扱う際は、ぜひこの記事を参考にしてください。
コメント