【MyBatis笔记整理七】动态SQL

版权声明:本文为 小异常 原创文章,非商用自由转载-保持署名-注明出处,谢谢!
本文网址:https://blog.csdn.net/sun8112133/article/details/104803554







MyBatis 作为一个 “半自动化” 的 ORM 框架,需要开发者手动定义 SQL 语句。在业务需求比较复杂的情况下,手动拼接 SQL 语句的工作量非常大,为了适用于不同的业务需求,往往需要做很多重复性的工作,这种工作对于开发者来讲比较耗费时间,同时也容易出错。

MyBatis 为我们提供了可以对 SQL 进行动态组装的能力,大大减少了我们编写代码的工作量。

本篇博客主要讲解 MyBatis动态 SQL 的使用,以及常用的 动态 SQL 标签。

动态 SQL 其实就是开发者在编写代码时定义的一个 SQL 模板,然后添加了一些特定的业务逻辑,可以自动生成不同的 SQL 语句,以应对各种不同的需求,使用起来也比较方便。


一、为什么要使用 动态 SQL

有些小伙伴可能还是不太明白为什么要使用 动态 SQL,它的好处到底是什么?

1、实体类

比如说有这么一个实体类 User,它有四个属性,分别是:idusernamepasswordage,有这样的需求:

  1. 通过 idusername 查询 User
  2. 通过 usernamepassword 查询 User
  3. 通过 passwordage 查询 User

2、方法

那么我们也要定义三个方法:

  1. User findByUser1(User user);
  2. User findByUser2(User user);
  3. User findByUser3(User user);

3、SQL 语句

我们的 SQL 语句也得写三个:

扫描二维码关注公众号,回复: 11371120 查看本文章
  1. select * from t_user where id = #{id} and username = #{username}
  2. select * from t_user where username = #{username} and password = #{password}
  3. select * from t_user where password = #{password} and age = #{age}

我们其实不难发现,这三个需求有很多相似的地方,我们能不能定义一个方法一条 SQL,加点逻辑判断就解决它呢?


动态 SQL 就是为我们解决这样的事情,它能够动态的判断属性如果不为 null,则加到 where 后面作为条件。这就是使用 动态 SQL 的好处。



二、常用的 动态 SQL 标签

1、if 标签

if 标签 相当于 Java 中的 if 语句,它常常与 test 属性联合使用。我就以上述案例以 if 标签 的形式编写:

<select id="findByUser" parameterType="com.demo.entity.User" resultType="com.demo.entity.User">
	select * from t_user where 1 = 1
	<if test="id != null">
		and id = #{id}
	</if>
	<if test="username != null">
		and username = #{username}
	</if>
	<if test="password != null">
		and password = #{password}
	</if>
	<if test="age != null">
		and age = #{age}
	</if>
</select>

2、where 标签

上面 if 标签select 语句我们加了一个 1=1 的绝对 true 语句,目的是为了防止语句错误,如果我们不加 1=1 语句,也可以使用 where 标签 进行替代。where 标签 最终会替换成 where 关键字。我们可以改写上面的配置:

<select id="findByUser" parameterType="com.demo.entity.User" resultType="com.demo.entity.User">
	select * from t_user
	<where>
		<if test="id != null">
			id = #{id}
		</if>
		<if test="username != null">
			and username = #{username}
		</if>
		<if test="password != null">
			and password = #{password}
		</if>
		<if test="age != null">
			and age = #{age}
		</if>
	</where>
</select>

3、choose、when、otherwise 标签

有些时候我们还需要多种条件的选择,在 Java 中我们可以使用 switchcasedefault 语句,而在映射器的动态语句中可以使用 choose、when、otherwise 标签。这里的 when 标签 默认都加了类似 Java 中的 break 语句。如下:

<select id="findByUser" parameterType="com.demo.entity.User" resultType="com.demo.entity.User">
	select * from t_user
	<where>
		<choose>
			<when test="id != null">
				id = #{id}
			</when>
			<when test="username != null">
				and username = #{username}
			</when>
			<when test="password != null">
				and password = #{password}
			</when>
			<when test="age != null">
				and age = #{age}
			</when>
			<otherwise>
				1=1
			</otherwise>
		</choose>
	</where>
</select>

4、trim 标签

这个标签可以帮助我们去掉一些特殊的 SQL 关键字,比如常见的 andor,此时就可以使用 trim 标签

  • prefix:代表语句的前缀;
  • prefixOverrides:代表前缀需要去掉的字符串;
  • suffix:表示语句的后缀;
  • suffixOverrides:代表后缀需要去掉的字符串。
<select id="findByUser" parameterType="com.demo.entity.User" resultType="com.demo.entity.User">
	select * from t_user
	<!-- 动态控制关键字 and,如果 where 跟着 and 就去掉 -->
	<trim prefix="where" prefixOverrides="and">
		<if test="id != null">
			and id = #{id}
		</if>
		<if test="username != null">
			and username = #{username}
		</if>
		<if test="password != null">
			and password = #{password}
		</if>
		<if test="age != null">
			and age = #{age}
		</if>
	</trim>
</select>

5、set 标签

update 语句中,如果我们只想更新某几个字段的值,这个时候可以使用 set 标签 配合 if 标签 来完成。注意: set 标签 遇到 , 会自动把 , 去掉。

<update id="update" parameterType="com.demo.entity.User">
	update t_user 
	<set>
		<if test="username != null">
			username = #{username},
		</if>
		<if test="password != null">
			password = #{password},	
		</if>
		<if test="age != null">
			age = #{age}
		</if>
	</set>
	where id = #{id}
</update>

6、foreach 标签

foreach 标签 是一个循环语句,它的作用是遍历集合,可以支持数组、List、Set 接口。它有以下几个属性:

  • collection:配置的是传递进来的参数名称;
  • item:配置的是循环中当前的元素;
  • index:配置的是当前元素在集合的位置下标;
  • openclose:配置的是以什么符号将这些集合元素包装起来;
  • separator:配置各个元素的间隔符。
<select id="findAllByUser" parameterType="com.demo.entity.User" resultType="com.demo.entity.User">
	select * from t_user
	<where>
		<foreach collection="ids" item="i" open="id in (" close=")" separator=",">
			#{i}
		</foreach>
	</where>
</select>


博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!



猜你喜欢

转载自blog.csdn.net/sun8112133/article/details/104803554