1.問題背景
Mybatis是我們日常專案中經常使用的框架,在專案中我們一般會使用like查詢作為模糊匹配字符進行搜索匹配,下面的Mapper.xml是我們使用like在專案中進行模糊匹配的常用方式:
<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>
這樣使用模糊查詢在分頁搜索中可以解決90%的匹配搜索功能,但是,還是有10%是陰溝翻船的事情,比如現在我要匹配檔案名detail中帶有'%'的檔案,使用這個陳述句就會造成搜索失效,直接回傳表中的limit所有資料,

造成這樣結果的原因就是由于像'%'或者'_'這樣的字符是通配字符,在模糊匹配的時候需要進行轉義執行,mysql執行決議器才會把它當成是單個字符進行匹配,否則則會按照匹配兩個''字符進行模糊匹配,得出全表搜索的錯誤結果,
2.解決方法
2.1.在入參SearchVo上進行特殊符號relpace轉換
使用Vo入參接收類對前端傳入的detail欄位進行判別處理,優先替換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簡單來說就是escape '字符',表示在like中從帶有'字符'之后不再作為通配字符具有特殊含義,escape的理解可以參考另外一篇博客:
MYSQL escape用法 ,這里就不再做詳細介紹,
對應的解決方式如下:
①修改sql查詢陳述句,添加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進行通配符設定:
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.總結
以上兩種方式本質都是對查詢的關鍵字進行了處理,第一種方式更直接簡潔,第二種方式更容易理解,兩種方式我個人更推薦第一種,
另外還有一種處理方式是在代碼中使用攔截器或者AOP等技術進行統一攔截處理,有興趣的小伙伴可以搜索了解一下,涉及代碼較多,這里就不再一一展開,
本博文寫作要感謝“阿飛云”提供博文參考:
Mybatis中Like的使用方式以及一些注意點
寫的非常不錯,也在作業中解決了我的一個Bug單問題,可以結合一起作為參考,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/303459.html
標籤:其他
上一篇:Git LFS 3.0.0 發布,對大檔案進行版本控制的 Git 擴展
下一篇:Java陣列超詳解
