1. 程式人生 > 實用技巧 >Mybatis動態sql是做什麼的?都有哪些動態sql?簡述一下動態sql的執行原理?

Mybatis動態sql是做什麼的?都有哪些動態sql?簡述一下動態sql的執行原理?

1.Mybatis動態sql是做什麼的?都有哪些動態sql?簡述一下動態sql的執行原理?

1.動態SQL的概念

​ 動態sql是指在進行sql操作的時候,傳入的引數物件或者引數值,根據匹配的條件,有可能需要動態的去判斷是否為空,迴圈,拼接等情況;

2.動態Sql的標籤大致有以下幾種
if 和 where 標籤和include標籤

​ if標籤中可以判斷傳入的值是否符合某種規則,比如是否不為空;

​ where標籤可以用來做動態拼接查詢條件,當和if標籤配合的時候,不用顯示的宣告類似where 1=1這種無用的條件,來達到匹配的時候and會多餘的情況;

​ include可以把大量重複的程式碼整理起來,當使用的時候直接include即可,減少重複程式碼的編寫

<!--動態Sql : where / if-->
<select id="findUserById"  resultType="com.lagou.pojo.User">
  select <include refid="userInfo"/> from user
  <where>
    <if test="id != null and id != 0">
      AND id = #{id}
    </if>
    <if test="name != null and name != ''">
      AND name = #{name}
    </if>
  </where>
</select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
choose、when、otherwise 標籤

​ 類似於 Java 中的 switch、case、default。只有一個條件生效,也就是隻執行滿足的條件 when,沒有滿足的條件就執行 otherwise,表示預設條件

<!--動態Sql: choose、when、otherwise 標籤-->
<select id="findUserById" resultType="com.lagou.pojo.User">
  select * from user
  <where>
    <choose>
      <when test="name != null and name != ''">
        AND name = #{name}
      </when>
      <otherwise>
        AND id = #{id}
      </otherwise>
    </choose>
  </where>
</select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

foreach 標籤

​ foreach標籤可以把傳入的集合物件進行遍歷,然後把每一項的內容作為引數傳到sql語句中,裡面涉及到item(具體的每一個物件),index(序號),open(開始符),close(結束符),separator(分隔符)

<!--動態Sql: foreach標籤, 批量插入-->
<insert id="insertBatch" useGeneratedKeys="true" keyProperty="id">
  insert into user (id, name)
  values
  <foreach collection="list" item="user" separator="," >
    (#{user.id}, #{user.name})
  </foreach>
</insert>

<!--動態Sql: foreach標籤, in查詢-->
<select id="dynamicSqlSelectList" resultType="com.lagou.pojo.User">
  SELECT * from user WHERE id in
  <foreach collection="list" item="id" open="(" close=")" separator="," >
    #{id}
  </foreach>
</select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

map引數

​ < map> 標籤需要結合MyBatis的引數註解 @Param()來使用,需要告訴Mybatis配置檔案中的collection="map"裡的map是一個引數

<!--動態Sql: foreach標籤, map引數查詢-->
<select id="findByMap" resultType="com.lagou.pojo.User">
  select * from user WHERE
  <foreach collection="map" index="key" item="value"  separator="=">
    ${key} = #{value}
  </foreach>
</select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

set標籤

​ 適用於更新中,當匹配某個條件後,才會對該欄位進行更新操作

<!--動態Sql: set 標籤-->
<update id="updateSet" parameterType="com.lagou.pojo.User">
  update user
  <set>
    <if test="name != null and name != ''">
      name = #{name},
    </if>
  </set>
  where id = #{id}
</update>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
trim標籤

是一個格式化標籤,主要有4個引數:

prefix(字首)

prefixOverrides(去掉第一個標記)

suffix(字尾)

suffixOverrides(去掉最後一個標記)

<!--動態Sql: trim 標籤-->
<select id="findUser" resultType="com.lagou.pojo.User">
  select * from user
  <trim prefix="where" suffix="order by id" prefixOverrides="and | or" suffixOverrides=",">
    <if test="name != null and name != ''">
      AND name = #{name}
    </if>
    <if test="id != null">
      AND id = #{id}
    </if>
  </trim>
</select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
3.動態sql的執行原理
  • 首先在解析xml配置檔案的時候,會有一個SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass) 的操作
  • createSqlSource底層使用了XMLScriptBuilder來對xml中的標籤進行解析
  • XMLScriptBuilder呼叫了parseScriptNode()的方法,
  • 在parseScriptNode()的方法中有一個parseDynamicTags()方法,會對nodeHandlers裡的標籤根據不同的handler來處理不同的標籤
  • 然後把DynamicContext結果放回SqlSource中
  • DynamicSqlSource獲取BoundSql
  • 在Executor執行的時候,呼叫DynamicSqlSource的解析方法,並返回解析好的BoundSql,和已經排好序,需要替換的引數

​ 簡單的說:就是使用OGNL從sql引數物件中計算表示式的值,根據表示式的值動態拼接sql

原文:https://blog.csdn.net/weixin_42427551/article/details/105835737