1. 程式人生 > 其它 >MyBatis 模糊查詢

MyBatis 模糊查詢

MyBatis 有 4 種方式可以實現模糊查詢。

員工資訊表 ( tb_employee ) 如下:

方式一

<select id="selectByName" resultType="EmployeeEntity">
     select * from tb_employee where name like #{name}
</select>

此種方式需要呼叫介面方法傳參時,手動的去新增 “%” 萬用字元,即

SqlSession sqlSession = MyBatisUtil.getSession();
IEmpolyeeDao empolyeeDao = sqlSession.getMapper(IEmpolyeeDao.class);
EmployeeEntity = IEmpolyeeDao.selectByName("%"+"張"+"%");
MyBatisUtil.closeSesion(sqlSession);

這種方式可以實現模糊查詢,但是有一點不方便的地方就是在呼叫介面 selectByName() 方法傳參時需要手動的新增 "%" 號萬用字元,有些麻煩。

方式二

你可能會想到,能否在對映配置檔案中直接將”%“號萬用字元寫好呢?如下:

<select id="selectByName" resultType="EmployeeEntity">
     select * from tb_employee where name like %#{name}%
</select>

但是,測試後你會發現,程式會報錯,錯誤原因是:缺少單引號。

這時你可能會這樣想了,那乾脆加一個“單引號”不就得了,如下:

<select id="selectByName" resultType="EmployeeEntity">
     select * from tb_employee where name like '%#{name}%'
</select>

測試後發現,程式依然會報錯,原因是:如果加上單引號,那麼就當成是一個字串,而 #{ } 寫在字串中不能識別,正確的做法是將#{ }改寫成 ${ } 這種形式,如下:

<select id="selectByName" resultType="EmployeeEntity">
     select * from tb_employee where name like '%${name}%'
</select>

測試後發現,程式終於沒報錯了。但是這種方式有一個美中不足的地方,就是它是以拼接字串的方式生成 sql,這樣做會引發 sql 注入的問題。(SQL 注入是黑客常用的一種攻擊技術,想知道詳情請搜尋看我的另一篇專門介紹 SQL 注入問題以及防禦辦法的文章)

方式三

前兩種方式,雖然可以解決模糊查詢的問題,但是都不怎麼好,要麼手動新增太麻煩,要麼有 SQL 注入的安全問題。有沒有什麼辦法,能夠兩全其美呢?有的,我們可以藉助 mysql 的字串拼接 concat 函式,如下:

<select id="selectByName" resultType="EmployeeEntity">
     select * from tb_employee where name like concat( '%' , #{name}, '%')
</select>

這是 concat( '%' , #{name}, '%') 的作用就將三個字串拼接起來。

方式四

當然對於方式三,也可以使用 ${} 的方式,不過需要特別留意單引號的問題。

<select id="selectByName" resultType="EmployeeEntity">
     select * from tb_employee where name like concat( '%' , '${name}', '%')
</select>

總結

  • '#{}'是預編譯處理,MyBatis 在處理 #{ }時,它會將sql中的#{ }替換為 ?號,然後呼叫JDBC 中 PreparedStatement 的 set 方法來賦值,傳入字串後會自動在值兩邊加上單引號,使用佔位符的方式提高效率,可以防止 sql 注入問題(主要使用方式)

  • '${ }' 表示拼接 sql 串,將接收到引數的內容不加任何修飾拼接在 sql 中,可能引發 sql 注入問題(一般很少使用)