1. 程式人生 > 其它 >Springboot-4:Mybatis之動態SQL和快取

Springboot-4:Mybatis之動態SQL和快取

技術標籤:javawebmybatis

一、 動態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。
測試結果如下:
g-blog.csdnimg.cn/2021012421195977.png)
提醒: 如果每個case都符合,那麼只會拼接第一個<when>的SQL!

更新ING~~~~~~~~