Mybatis、MongoDB 或者 Solr 引擎在查询数据的时候,如果存在%_等通配符时,这些特殊符号都不会被作为字符串进行搜索,会导致查询不出数据或者查询出来的数据是不准确的,这个时候就需要对特殊字符进行转义。
例如:
<if test="name != null and name != ''" >
AND content.name like CONCAT(#{name},'%')
</if>
按原先的预想是该字段会进行左匹配,但是如果入参name是%测试%,则实际上搜索的是全匹配搜索了带有测试的所有值。
原因就是使用 LIKE 关键字进行模糊查询时,%、下划线 和 [] 单独出现时,会被认为是通配符,所以需要进行转义,然后通过 ESCAPE 告诉数据库转义字符后的字符为实际值。
首先对关键字进行转义,使用 StringEscapeUtils 对 Java 中特殊字符进行转义,或者使用以下的工具类
/**
* sql模糊搜索时,对查询字段作特殊处理
* 通配符转义处理后,like 语句后面加上 ESCAPE '/'
* @param s 需要转义的字符串
* @return 返回转义后的字符串
*/
public static String escapeQueryChars(String s) {
if (StringUtils.isBlank(s)) {
return s;
}
// 只需要转义/%_
s = s.replaceAll("/", "//");
s = s.replaceAll("%", "/%");
s = s.replaceAll("_", "/_");
return s;
// 遍历每个字符,如果是特殊字符则在前面拼接/
// StringBuilder sb = new StringBuilder();
// for (int i = 0; i < s.length(); i++) {
// char c = s.charAt(i);
// if (c == '%' || c == '_' || c == '/'
// || c == '\\' || c == '+' || c == '-' || c == '(' || c == ')'
// || c == ':' || c == '^' || c == '[' || c == ']' || c == '\"'
// || c == '{' || c == '}' || c == '~' || c == '*' || c == '?'
// || c == '|' || c == '&' || c == ';' || c == '.'|| c == '!'
// || c == '$' || Character.isWhitespace(c)
// ) {
// sb.append('/');
// }
// sb.append(c);
// }
// return sb.toString();
}
在 mabatis 的 mapper 文件中,在 like 语句后面加上 ESCAPE,告诉数据库转义字符为 “/”,转义字符后面的 % 或_就不作为通配符使用
like CONCAT(#{name},'%') ESCAPE '/'
也可以使用内置函数来进行模糊搜索 (locate () 等)
1、使用 locate ()
select `name` from `user` where locate('keyword', `condition`)>0
找到返回的结果都大于 0,没有查找到返回 0;
2、使用 instr ()
select`name` from `user` where instr(`condition`, ‘keyword’ )>0
唯一不同的是查询内容的位置不同
3、使用 position ()
select`name` from `user` where position(‘keyword’ IN `condition`)
4、使用 find_in_set ()
find_in_set (str,strlist),strlist 必须要是以逗号分隔的字符串
参考:
mybatis 对特殊字符的模糊查询:https://blog.csdn.net/wslyk606/article/details/85321759
mybatis 模糊查询特殊字符的处理:https://www.baidu.com/link?url=vVdwynxLrMPE-WMbEROJ5PrwhIv9V8pLm7h9dgu8JzmxVP4ulUv5hqIOuNFMWsaoeNGxIIpyuMsijxnAovLp2a&wd=&eqid=f256af3a000133a6000000065fa3e6eb
MyBatis 模糊查询特殊字符无效问题:https://baijiahao.baidu.com/s?id=1649824285248362226&wfr=spider&for=pc
Java 特殊字符转义:https://blog.csdn.net/weixin_40584261/article/details/88756970
MYSQL escape 用法 -- 转义:https://www.cnblogs.com/YuyuanNo1/p/12921578.html
使用 StringEscapeUtils 对 Java 中特殊字符进行转义和反转义:https://www.baidu.com/link?url=htBcQCkaqbCnnarInkA3l_FmM_vO_wtnRh9P70HI2d37TNkya6Xin1Pirfrx7XSyrJVrcpjelz-RWgG_MNTB1K_SLVqP1W-Owg73R3v4XhS&wd=&eqid=c063a264000b95d2000000065fa4ac17
常用工具类 StringEscapeUtils:https://my.oschina.net/mousai/blog/88832