【MyBatis】深入解析MyBatis:高效操作数据库技术详解

💓 博客主页:从零开始的-CodeNinja之路

⏩ 收录文章:【MyBatis】深入解析MyBatis:高效操作数据库技术详解

🎉欢迎大家点赞👍评论📝收藏⭐文章

目录

  • 动态SQL
    • [1. \<if>标签](#1. <if>标签)
    • [2. \<trim>标签](#2. <trim>标签)
    • [3. \<where>标签](#3. <where>标签)
    • [4. \<set>标签](#4. <set>标签)
    • [5. \<foreach>标签](#5. <foreach>标签)
    • [6. \<include>标签](#6. <include>标签)

动态SQL

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

1. <if>标签

在注册用户的时候,可能会有这样⼀个问题,如下图所示:

注册分为两种字段:必填字段和非必填字段,那如果在添加用户的时候有不确定的字段传入,程序应该如何实现呢?

这个时候就需要使用动态标签来判断了,比如添加的时候性别gender为非必填字段,具体实现如下:

cpp 复制代码
Integer insertUserByCondition(UserInfo userInfo);

Mapper.xml实现:

cpp 复制代码
<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字段有默认值,就会设置为默认值

2. <trim>标签

之前的插入用户功能,只是有⼀个gender字段可能是选填项,如果有多个字段,⼀般考虑使用标签结合标签,对多个字段都采取动态生成的方式。

标签中有如下属性:

  • prefix:表示整个语句块,以prefix的值作为前缀

  • suffix:表示整个语句块,以suffix的值作为后缀

  • prefixOverrides:表示整个语句块要去除掉的前缀

  • suffixOverrides:表示整个语句块要去除掉的后缀

调整Mapper.xml的插入语句为:

cpp 复制代码
<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>

3. <where>标签

看下⾯这个场景,系统会根据我们的筛选条件,动态组装where条件

需求:传入的用户对象,根据属性做where条件查询,用户对象中属性不为null的,都为查询条件

原有SQL:

cpp 复制代码
SELECT * FROM userinfo WHERE age = 18 AND gender = 1 AND delete_flag =0

Mapper.xml实现

cpp 复制代码
<select id="queryByCondition" resultType="com.example.demo.model.UserInfo">

	select id, username, age, gender, phone, delete_flag, create_time,update_timefrom 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子句,⽽且会⾃动去除子句的开头的AND或OR

以上标签也可以使用 替换,但是此种情况下,当子元素都没有内容时,where关键字也会保留

4. <set>标签

需求:根据传入的用户对象属性来更新用户数据,可以使用标签来指定动态内容.

接口定义:根据传入的用户id属性,修改其他不为null的属性

cpp 复制代码
Integer updateUserByCondition(UserInfo userInfo);

Mapper.xml

cpp 复制代码
<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语句中)

以上标签也可以使用 替换。

5. <foreach>标签

对集合进行遍历时可以使用该标签。标签有如下属性:

• collection:绑定方法参数中的集合,如List,Set,Map或数组对象

• item:遍历时的每⼀个对象

• open:语句块开头的字符串

• close:语句块结束的字符串

• separator:每次遍历之间间隔的字符串

需求:根据多个userid,删除用户数据

接口方法:

cpp 复制代码
void deleteByIds(List<Integer> ids);

ArticleMapper.xml中新增删除sql:

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

6. <include>标签

问题分析:

  • 在xml映射文件中配置的SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码

我们可以对重复的代码片段进行抽取,将其通过 标签封装到⼀个SQL片段,然后再通过<include> 标签进行引用。

  • :定义可重用的SQL片段
  • :通过属性refid,指定包含的SQL片段
cpp 复制代码
<sql id="allColumn">
id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>

通过 标签在原来抽取的地方进行引用。操作如下:

cpp 复制代码
<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>
相关推荐
kinlon.liu10 分钟前
零信任安全架构--持续验证
java·安全·安全架构·mfa·持续验证
李小星同志12 分钟前
高级算法设计与分析 学习笔记6 B树
笔记·学习
哈喽,树先生17 分钟前
1.Seata 1.5.2 seata-server搭建
spring·springcloud
霜晨月c23 分钟前
MFC 使用细节
笔记·学习·mfc
王哲晓31 分钟前
Linux通过yum安装Docker
java·linux·docker
java66666888836 分钟前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存36 分钟前
源码分析:LinkedList
java·开发语言
小江湖199437 分钟前
元数据保护者,Caesium压缩不丢重要信息
运维·学习·软件需求·改行学it
执键行天涯37 分钟前
【经验帖】JAVA中同方法,两次调用Mybatis,一次更新,一次查询,同一事务,第一次修改对第二次的可见性如何
java·数据库·mybatis
Darling_001 小时前
LeetCode_sql_day28(1767.寻找没有被执行的任务对)
sql·算法·leetcode