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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM