1.問(wèn)題背景
Mybatis是我們?nèi)粘m?xiàng)目中經(jīng)常使用的框架,在項(xiàng)目中我們一般會(huì)使用like查詢作為模糊匹配字符進(jìn)行搜索匹配,下面的Mapper.xml是我們使用like在項(xiàng)目中進(jìn)行模糊匹配的常用方式:
<sql id="searchCondition"> <trim prefix="where" prefixOverrides="and|or"> <if test="paramVo.detail != null and paramVo.detail != '' "> and idwl.detail like concat('%', #{paramVo.detail, jdbcType=VARCHAR}, '%') </if> </trim> </sql>
這樣使用模糊查詢?cè)诜猪?yè)搜索中可以解決90%的匹配搜索功能,但是,還是有10%是陰溝翻船的事情。比如現(xiàn)在我要匹配文件名detail中帶有'%'的文件,使用這個(gè)語(yǔ)句就會(huì)造成搜索失效,直接返回表中的limit所有數(shù)據(jù)。
造成這樣結(jié)果的原因就是由于像'%'或者'_'這樣的字符是通配字符,在模糊匹配的時(shí)候需要進(jìn)行轉(zhuǎn)義執(zhí)行,mysql執(zhí)行解析器才會(huì)把它當(dāng)成是單個(gè)字符進(jìn)行匹配,否則則會(huì)按照匹配兩個(gè)''字符進(jìn)行模糊匹配,得出全表搜索的錯(cuò)誤結(jié)果。
2.解決方法
2.1.在入?yún)earchVo上進(jìn)行特殊符號(hào)relpace轉(zhuǎn)換
使用Vo入?yún)⒔邮疹悓?duì)前端傳入的detail字段進(jìn)行判別處理,優(yōu)先替換replace特殊字符:
public class SerachParamVO { private String productVersion; private String detail; private Integer releaseType; private String createUser; private String createUserAccount; private Date createTime; private String description; public void setDetail(String detail) { this.detail = detail.replaceAll("%", "\\\\%") .replaceAll("_", "\\\\_"); } }
2.2.使用ESCAPE
使用ESCAPE:escape簡(jiǎn)單來(lái)說(shuō)就是escape '字符',表示在like中從帶有'字符'之后不再作為通配字符具有特殊含義,escape的理解可以參考另外一篇博客:
MYSQL escape用法,這里就不再做詳細(xì)介紹。
對(duì)應(yīng)的解決方式如下:
①修改sql查詢語(yǔ)句,添加escape:
<sql id="searchCondition"> <trim prefix="where" prefixOverrides="and|or"> <if test="paramVo.detail != null and paramVo.detail != '' "> and idwl.detail like concat('%', #{paramVo.detail, jdbcType=VARCHAR}, '%') escape '/' </if> </trim> </sql>
②傳入SearchVo進(jìn)行通配符設(shè)置:
public class SerachParamVO { private String productVersion; private String detail; private Integer releaseType; private String createUser; private String createUserAccount; private Date createTime; private String description; public void setDetail(String detail) { this.detail = detail.replaceAll("%", "/%") .replaceAll("_", "/_"); } }
2.3.總結(jié)
以上兩種方式本質(zhì)都是對(duì)查詢的關(guān)鍵字進(jìn)行了處理,第一種方式更直接簡(jiǎn)潔,第二種方式更容易理解。兩種方式我個(gè)人更推薦第一種。
另外還有一種處理方式是在代碼中使用攔截器或者AOP等技術(shù)進(jìn)行統(tǒng)一攔截處理,有興趣的小伙伴可以搜索了解一下。涉及代碼較多,這里就不再一一展開(kāi)。
本博文寫(xiě)作要感謝“阿飛云”提供博文參考:
Mybatis中Like的使用方式以及一些注意點(diǎn)
寫(xiě)的非常不錯(cuò),也在工作中解決了我的一個(gè)Bug單問(wèn)題,可以結(jié)合一起作為參考。
到此這篇關(guān)于MyBatis中模糊搜索使用like匹配帶%字符時(shí)失效問(wèn)題的文章就介紹到這了,更多相關(guān)MyBatis like模糊搜索內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://www.cnblogs.com/yif0118/archive/2021/09/27/15345931.html