Springboot-4:Mybatis之動態SQL和快取
一、 動態SQL
動態 SQL 是 MyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應該能理解根據不同條件拼接 SQL 語句有多痛苦,例如拼接時要確保不能忘記新增必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL,可以徹底擺脫這種痛苦。
如果之前用過 JSTL 或任何基於類 XML 語言的文字處理器,你對動態 SQL 元素可能會感覺似曾相識,因為大致寫法是差不多的。
1、if 語句
if語句是最簡單的,通常用在where處新增條件拼接查詢條件。
mapper.xml
<select id=" getStudentsIf"
resultType="Student" parameterType="map">
select id,name
from student
where 1=1
<if test="deptId != null">
and dept_id = #{deptId}
</if>
</select>
測試程式碼(下面的例子中測試都是靠map這種傳參)
Map map = new HashMap<> ();
map.put("deptId",3);
List<Student> list = studentMapper.getStudentsIf(map);
list.forEach(System.out::println);
通過這個例子可以看到,通過if語句判斷引數中deptId是否為空,根據判定結果追加SQL。如果這是deptId是3則查詢班級ID是3是學生,null則查詢全部學生。
問 :那裡的where 1=1是啥?
答:為了保證sql可以執行。
問:怎麼優化?
答:這裡介紹一下<where>
標籤,我們知道在拼接條件時,從第二個條件開始要加OR或者AND,但若只有一個條件就不用加AND,但是如何控制呢?<where>
<where>
中有條件成立,他就會自動加上在sql上拼接上“where”,如果第一個成立條件要拼接的sql是and id = #{id}
,就會自動幫助我們省忽略and,但若<where>
中無成立的條件,mybatis咋會執行<where>
之前的語句。
<select id="getStudentsIf"
resultType="Student" parameterType="map">
select id,name
from student
<where>
<if test="deptId != null">
and dept_id = #{deptId}
</if>
</where>
</select>
可見,利用where標籤才是高階做法。
2、choose、when、otherwise
如果我們不想要全部的條件,只想取其中一個,而上面的if是無數個單獨的if語句,沒有else if 和else,針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch-case語句。
<choose>
標籤相當於最外層的switch,而<when>
相當於每一個case。<otherwise>
是預設的。
mapper.xml
<select id="getStudentsChoose" resultType="Student" parameterType="map">
select id,name,dept_id
from student
<where>
<choose>
<when test="name != null">
name = #{name}
</when>
<when test="deptId != null">
and dept_id = #{deptId}
</when>
<otherwise>
and id = #{id}
</otherwise>
</choose>
</where>
在這裡我們傳入的map中只有{"deptId":2}
,所以mybatis智慧拼接上了dept_id = #{deptId}
,而其他對立條件不生效。
測試結果如下:
但若傳入一個空的map,可見mybatis拼接的是<otherwise>
中的SQL。
測試結果如下:
提醒: 如果每個case都符合,那麼只會拼接第一個<when>
的SQL!
更新ING~~~~~~~~