最近在寫DAO層的時候,遇到一個問題,就是使用like進行模糊查詢時,輸入下划線,無法精確查到數據,而是返回所有的數據。
這讓我很好奇,百度之后才發現,原來是因為有些特殊字符需要進行轉義才可以進行查詢。
首先理解一下什么是特殊字符。
在ascii碼表中,特殊字符的范圍如下。即從32~47 58~64 91~96 123~126。
模糊查詢時,有兩種方法可以進行轉換。
1. 使用REGEXP_LIKE方法,這是個使用正則表達式來查詢的方法,因此有此字符需要進行轉義才能查詢,如$ *等,轉義符為反斜杠\,因此反斜杠也要進行轉。這里只討論字符中包含某字符串的情況,對於正則表達式的匹配不作討論。
2. 使用like關鍵字,配合escape關鍵字進行轉義。
字符匹配操作可以使用通配符 “%” 和 “_”:
%:表示任意個字符,包括零個;
_:表示一個任意字符;上文說到輸入下划線會查出所有就是因為只要有任意一個字符都可以查詢出來。
同時,對於單引號,在oracle中,例如select * from tableTest t where t.name like '%'%' escape '\' 那么like語句中的'會與前一個單引號匹配,造成語法錯誤。使用轉義符號也無法正常結束。需要將單個單引號轉成兩個單引號,select * from tableTest t where t.name like '%''%' escape '\'
因此,上面兩個字符,以及用來轉義的字符(通常使用反斜杠)需要進行轉義。


那么問題又來了,在Java代碼中,如果使用JDBC的PreparedStatement進行預編譯,是不是就可以不需要進行轉義了?
just do it!
答案是否定的,還是需要進行轉義。注意下面,沒有進行轉義,查出的結果仍然是所有記錄。

轉義后就精確了。

還應注意兩點:
1. jdbc會自動加上單引號,賦值時不必添加單引號
2. jdbc會自動將單個單引號轉換成兩個的,賦值時不必寫兩個單引號
