MyBatisでLIKE検索時の特殊文字のエスケープ処理

Java

データベースで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クエリを扱う際は、ぜひこの記事を参考にしてください。

コメント

タイトルとURLをコピーしました