JAVAEE之Spring Boot日志(进阶)

本文详细介绍了Mybatis中动态SQL的使用,包括<if>标签处理必填和非必填字段、<trim>标签处理多个字段动态生成、<where>和<set>标签在查询和更新中的应用,以及如何通过<foreach>遍历集合和<include>重用SQL片段以提高代码效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 动态SQL

动态 SQL 是Mybatis的强⼤特性之⼀,能够完成不同条件下不同的 sql 拼接。

2.<if>标签

当出现必填字段和非必填字段的时候使用该标签

<insert id="insertUserByCondition">
 INSERT INTO userinfo (
 username,
 `password`,
 age,
 <if test="gender != null">
 gender,
 </if>
 phone)
 VALUES (
 #{username},
 #{age},
 <if test="gender != null">
 #{gender},
 </if>
 #{phone})
</insert>

注意 test 中的 gender,是传⼊对象中的属性,不是数据库字段
Q: 可不可以不进⾏判断, 直接把字段设置为null呢?
A: 不可以, 这种情况下, 如果gender字段有默认值, 就会设置为默认值

 3.<trim>标签

之前的插⼊⽤⼾功能,只是有⼀个 gender 字段可能是选填项,如果有多个字段,⼀般考虑使⽤标签结
合标签,对多个字段都采取动态⽣成的⽅式。
标签中有如下属性:
• prefix:表⽰整个语句块,以prefix的值作为前缀
• suffix:表⽰整个语句块,以suffix的值作为后缀
• prefixOverrides:表⽰整个语句块要去除掉的前缀
• suffixOverrides:表⽰整个语句块要去除掉的后缀
调整 Mapper.xml 的插⼊语句为:

<insert id="insertUserByCondition">
 INSERT INTO userinfo
 <trim prefix="(" suffix=")" suffixOverrides=",">
 <if test="username !=null">
 username,
 </if>
 <if test="password !=null">
 `password`,
 </if>
 <if test="age != null">
 age,
 </if>
 <if test="gender != null">
 gender,
 </if>
 <if test="phone != null">
 phone,
 </if>
 </trim>
 VALUES
 <trim prefix="(" suffix=")" suffixOverrides=",">
 <if test="username !=null">
 #{username},
 </if>
 <if test="password !=null">
 #{password},
 </if>
 <if test="age != null">
 #{age},
</if>
 <if test="gender != null">
 #{gender},
 </if>
 <if test="phone != null">
#{phone}
 </if>
 </trim>
</insert>

 在以上 sql 动态解析时,会将第⼀个 部分做如下处理:
• 基于 prefix 配置,开始部分加上 (
• 基于 suffix 配置,结束部分加上 )
• 多个 组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于
suffixOverrides 配置去掉最后⼀个 ,
• 注意 <if test="username !=null"> 中的 username 是传⼊对象的属性

4.<where>标签 

<select id="queryByCondition" resultType="com.example.demo.model.UserInfo">
 select id, username, age, gender, phone, delete_flag, create_time, 
update_time
 from userinfo
 <where>
 <if test="age != null">
 and age = #{age}
 </if>
 <if test="gender != null">
 and gender = #{gender}
 </if>
<if test="deleteFlag != null">
 and delete_flag = #{deleteFlag}
 </if>
 </where>
</select>

<where> 只会在⼦元素有内容的情况下才插⼊where⼦句,⽽且会⾃动去除⼦句的开头的AND或
OR
以上标签也可以使⽤ <trim prefix="where" prefixOverrides="and"> 替换, 但是此种
情况下, 当⼦元素都没有内容时, where关键字也会保留

5.<set>标签 

需求: 根据传⼊的⽤⼾对象属性来更新⽤⼾数据,可以使⽤标签来指定动态内容.
接⼝定义: 根据传⼊的⽤⼾ id 属性,修改其他不为 null 的属性

<update id="updateUserByCondition">
 update userinfo
 <set>
 <if test="username != null">
 username = #{username},
 </if>
<if test="age != null">
 age = #{age},
 </if>
 <if test="deleteFlag != null">
 delete_flag = #{deleteFlag},
 </if>
 </set>
 where id = #{id}
</update>

<set> :动态的在SQL语句中插⼊set关键字,并会删掉额外的逗号. (⽤于update语句中)
以上标签也可以使⽤ <trim prefix="set" suffixOverrides=","> 替换。

6. <foreach>标签

对集合进⾏遍历时可以使⽤该标签。标签有如下属性:
• collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
• item:遍历时的每⼀个对象
• open:语句块开头的字符串
• close:语句块结束的字符串
• separator:每次遍历之间间隔的字符串
需求: 根据多个userid, 删除⽤⼾数据
接⼝⽅法:
void deleteByIds(List<Integer> ids); 

<delete id="deleteByIds">
 delete from userinfo
 where id in
 <foreach collection="ids" item="id" separator="," open="(" close=")">
 #{id}
 </foreach>
</delete>

7.<include>标签

问题分析:
• 在xml映射⽂件中配置的SQL,有时可能会存在很多重复的⽚段,此时就会存在很多冗余的代码

我们可以对重复的代码⽚段进⾏抽取,将其通过 <sql> 标签封装到⼀个SQL⽚段,然后再通过
<include> 标签进⾏引⽤。
• <sql> :定义可重⽤的SQL⽚段
• <include> :通过属性refid,指定包含的SQL⽚段

<sql id="allColumn">
 id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>

//通过 <include> 标签在原来抽取的地⽅进⾏引⽤。操作如下:
<select id="queryAllUser" resultMap="BaseMap">
 select
 <include refid="allColumn"></include>
 from userinfo
</select>

<select id="queryById" resultType="com.example.demo.model.UserInfo">
 select
 <include refid="allColumn"></include>
 from userinfo where id= #{id}
</select>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值