【SSM框架】Mybatis详解(源码自取)之动态sql详解
- 🧛♂️个人主页:杯咖啡
- 💡进步是今天的活动,明天的保证!
- ✨目前正在学习:SSM框架,算法刷题
- 👉本文收录专栏:SSM框架解析
- 🙌牛客网,刷算法过面试的神级网站,用牛客你也牛。 👉免费注册和我一起学习刷题👈
- 🐳希望大家多多支持🥰一起进步呀!
- 😎The man who fears losing has already lost.
怕输的人已经输了。 - 《权力的游戏》
✨前言
上一节我们复习了优化注册,#{}与¥{}区别,返回主键,UUID
这一节我们复习动态sql
和我一起复习下去你可以获得一个比较完美框架demo
,并且深刻体会框架
。
坚持到最后的源码解析
你会收获更多哦,加油坚持!!!
@[TOC]
什么是动态sql
可以定义代码片断,可以进行逻辑判断,可以进行循环处理(批量处理),使条件判断更为简单.
我们假设一个场景,如果我们需要利用姓名模糊搜索或者需要利用性别进行搜索,或者我们需要两个条件同时进行限制搜索。
我们知道为了防止sql注入,我们使用的都是预编译的语句,我们的sql语句就要写三套。那么mybatis就很方便的为我们提供了自动判断自动修改sql语句的方式,使我们的工作更加方便。
标签详解
<sql>
1)<sql>:用来定义代码片断,可以将所有的列名,或复杂的条件定义为代码片断,供使用时调用.
<include>
2)<include>:用来引用<sql>定义的代码片断.
<!--定义代码片断--> <sql id="allColumns"> id,username,birthday,sex,address </sql> //引用定义好的代码片断 <select id="getAll" resultType="users" > select <include refid="allColumns"></include> from users </select>
<if>
3)<if>:进行条件判断
test条件判断的取值可以是实体类的成员变量,可以是map的key,可以是@Param注解的名称.
<where>
4)<where>:进行多条件拼接,在查询,删除,更新中使用.
<!--UserMapper.xml文件中--> <select id="getByCondition" parameterType="users" resultType="users"> select <include refid="allColumns"></include> from users <where> <if test="userName != null and userName != ''"> and username like concat('%',#{userName},'%') </if> <if test="birthday != null"> and birthday = #{birthday} </if> <if test="sex != null and sex != ''"> and sex = #{sex} </if> <if test="address != null and address != ''"> and address like concat('%',#{address},'%') </if> </where> </select>
我们看一下输入不同的查询值的sql语句的不同
当我们什么条件都没有输入,就会查询全部
当我们输入了性别,可以看到我们的语句是这样的
当我们由加入地区的模糊查询,sql语句是这样的
这就是动态sql给我们提供的便利,我们只需要输入我们的条件就好了,mybatis可以自动为我们调整sql语句
我们在做模糊查询的时候的一个细节:我们尽量使用concat()函数进行字符串的拼接,而不是直接like 'xxxx',在我们使用函数的时候更加安全方便
<set>
5)<set>:有选择的进行更新处理,至少更新一列.能够保证如果没有传值进来,则数据库中的数据保持不变.
这里我们需要更新的话,我们就要把这一行的所有指标都赋值,才能完成更新。如果我们只赋值一个属性(只传入我们需要修改的属性)那么其他没赋值的就变成null了。我们来看一下
正常我们需要给所有指标(属性),全部赋值可以完成更新,那么我们试试只赋值一个属性的情况
一定要记得在我们的实体类增加新的构造方法哦,不然构造会报错哦
运行看结果
这里运行成功了,细心的小伙伴已经发现问题了,我们看看数据库里面吧,显然易见
本来我只想修改名字,其他的不需要修改的我不想动,我还就只想输入我想修改的值,其他的为啥变成了NULL呢???那么这里<set>
标签来帮助你,代码如下:
<update id="updateBySet" parameterType="users"> update users <set> <if test="userName != null and userName != ''"> username = #{userName}, </if> <if test="birthday != null"> birthday = #{birthday}, </if> <if test="sex != null and sex != ''"> sex = #{sex}, </if> <if test="address != null and address != ''"> address =#{address} , </if> </set> where id = #{id} </update>
我们来看结果吧
这下我们的目的就达到了,完美解决
<foreach>
6)<foreach>:用来进行循环遍历,完成循环条件查询,批量删除,批量增加,批量更新.</foreach>
<!--查询实现--> <select id="getByIds" resultType="users"> select <include refid="allColumns"></include> from users where id in <foreach collection="array" item="id" separator="," open="(" close=")"> #{id} </foreach> </select>
<foreach>
参数详解:
collection:用来指定入参的类型,如果是List集合,则为list,如果是Map集合,则为map,如果是数组,则为array.
item:每次循环遍历出来的值或对象
separator:多个值或对象或语句之间的分隔符
open:整个循环外面的前括号
close:整个循环外面的后括号
<!--批量删除实现--> <delete id="deleteBatch" > delete from users where id in <foreach collection="array" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete> <!--批量增加实现--> <insert id="insertBatch"> insert into users(username, birthday, sex, address) values <foreach collection="list" item="u" separator="," > (#{u.userName},#{u.birthday},#{u.sex},#{u.address}) </foreach> </insert>
这里就只展示批量增加吧
✨总结
动态sql可以极大的简化我们sql的编写量,也是必须要掌握的东西哦!!!
下一节我们将继续复习指定参数位置,入参是map(重点掌握) ,返回值是map
本次源码放在代码仓库gitee,自取链接
#字节跳动数据分析师面经#