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