带你3分钟了解mybatis动态sql语句

系列文章目录

第一篇:3分钟快速了解Mybatis的基础配置
第二篇:带你3分钟了解Mybatis映射文件(sql,resultMap等映射)

前言

原创不易,如若喜欢,请点一点赞吧!!!!!!!!

动态sql语句是mybatis的强大特性之一,通过sql动态语句,可以简化sql语句写法的复杂性,减少sql语句代码量。可以帮助开发人员在编写sql功能语句时事倍功半。

一、动态sql语句中的元素

  • 主要动态sql语句如下:
元素说明
<if>判断语句,用于单条件分支判断
<choose>(<when>,<otherwise>)相当于java中的switch语句,用于多条件分支判断
<where>(<trim>,<set>)辅助元素,用于处理一些sql拼装,特殊字符问题
<foreach>循环语句,常用于in语句等列举条件中
<bind>从OGNL 表达式中创建一个变量,并将主主绑定到上下文,常用于模糊查询的sql 中

二、动态sql语句用法分析

创建项目,并完成mybatis 基础配置,创建mapper.xml文件,修改mapper.xml文件进行配置。

1.if 动态查询语句
1) 案例分析

在实际应用中,我们可能会通过多个条件来精确地查询某个数据。例如,要查找某个客户的信息,可以通过姓名和职业来查找客户,也可以不填写职业直接通过姓名来查找客户,还可以都不填写而查询出所有客户,此时姓名和职业就是非必须条件。但类似于这种情况,在My8atis中就可以通过<if>元素来实现。

<select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
		resultType="org.mybatis.beans.Customer">
		<!-- sql语句中的where 1=1不能省略-->
		select * from customer where 1=1
		<!-- 通过if条件语句来判断,执行第一条还是第二条或都不执行-->
		<if test="username!=null and username!=''">
			<!-- 模糊查询concat('%',#{username},'%')-->
			and username like concat('%',#{username},'%')
		</if>
		<if test="jobs!=null and jobs!=''">
			and jobs=#{jobs}
		</if>
	</select>
2)if语句使用分析:

使用<if>元素的test 属性分别对username 和jobs 进行了非空判断,如果传入的查询条件非空就进行动态SOL 组装。从而查询相应语句。使用if条件语句需要注意,所有的if语句均会被判断,而不是当第一个if语句为真时,则第二条if语句就不会被执行。当两个if语句都不满足条件时,程序会执行select * from customer where 1=1 语句,即将数据表中的所有数据查出。

2. <choose>(<when>,<otherwise>) 动态查询语句
1) 案例分析
"当客户名称不为空,则只根据客户名称进行客户筛选;
当客户名称为空,而客户职业不为空,则只根据客户职业进行客户筛选。
当客户名称和客户职业都为空,则要求查询出所有电话不为空的客户信息。"
在这种情况下,显然使用if语句是不合理的,在mybatis中提供了 `<choose>(<when>,<otherwise>)`语句来实现多分支条件查询
 <!--<choose>语句类似于java中的switch语句-->
	 <select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
		resultType="org.mybatis.beans.Customer">
		select * from customer where 1=1
		 <!--当满足username不为空时,则拼接username like concat('%',#{username},'%')-->
		 <!--当满足jobs不为空时,则拼接jobs=#{jobs}-->
		 <!--当username,jobs均为空时,则拼接and phone is not null-->
		<choose>
			<when test="username!=null and username!=''">
				and username like concat('%',#{username},'%')
			</when>
			<when test="jobs!=null and jobs!=''">
				and jobs=#{jobs}
			</when>
			<otherwise>
				and phone is not null
			</otherwise>
		</choose>
	 </select>
2)<choose>(<when>,<otherwise>)语句使用分析:
  • 当满足username不为空时,则拼接username like concat(’%’,#{username},’%’)
  • 当满足jobs不为空时,则拼接jobs=#{jobs} ,
  • 当username,jobs均为空时,则拼接and phoneis not null
3. <where>(<trim>)>动态查询语句
1) 案例分析

在前两个案例中,映射文件中编写的sql后面都加入了"where 1 =1" 的条件,如果将"where 1 =1"
条件去掉,则sql语句会出现语法错误那么在MyBatis 中,有没有什么办法不用加入"1 =1" 这样的条件,也能使拼接后的SQL 成立呢?

<!--<where>可以用来抵消select * from customer where 后1=1语句 
	 <select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
		resultType="org.mybatis.beans.Customer">
		<!--where 语句通过标签来写-->
		select * from customer 
		<where>
			<if test="username!=null and username!=''">
				and username like concat('%',#{username},'%')
			</if>
			<if test="jobs!=null and jobs!=''">
				and jobs=#{jobs}
			</if>
		</where>
	</select>
2)<where>(<trim>)>语句使用分析:

使用<where>元素对"where 1 =1" 条件进行了替换, <where>元素会自
动判断组合条件下拼装的SQL 语句,只有<where>元素内的条件成立时,才会在拼接SQL 中加入where 关键字,否则将不会添加;即使where 之后的内容有多余的"AND" 或"OR" , <where>元素也会自动将它们去除。

4. <set>动态查询语句
1) 案例分析

如果想要更新某一个对象,就需要发送所有的字段给持久化对象,然而实际应用中,大多数情况下都是更新的某一个或几个字段。如果更新的每一条数据都要将其所有的属性都更新一遍,那么其执行效率是非常差的。MyBatis 中提供了<set>元素来完成这一工作。<set>元素主要用于更新操作,其主要作用是在动态包含的SOL 语句前输出一个SET关键字,并将SOL 语句中最后一个多余的逗号去除。

<!--set元素主要用于更新数据-->
 <update id="updateCustomer" parameterType="org.mybatis.beans.Customer">
	 	update customer 
	 	<set>
	 		<if test="username!=null and username!=''">
	 			username = #{username},
	 		</if>
	 		<if test="jobs!=null and jobs!=''">
	 			jobs = #{jobs},
	 		</if>
	 		<if test="phone!=null and phone!=''">
	 			phone = #{phone},
	 		</if>
	 	</set>
	 		where id=#{id}
	 </update>
2)<set>语句使用分析:

将set语句与if语句结合起来,可以动态更新想要更新的数据,如果传入的更新字段非空,就将此字段进行动态SOL 组装,并更新此字段,否则此字段不执行更新。

需要注意的是: 在映射文件中使用<set><if>元素组合进行update 语句动态SQL 组装时,如果元素内也含的内容都为空,则会出现SQL 语法错误。所以在使用〈忧。元素进行字段信息更新时,要确保传入的更新字段不能都为空。

5. <foreach>动态查询语句
1) 案例分析

在实际开发中,有时可能会遇到这样的情况:假设在一个客户表中有1000 条数据,现在需要将id 值小于100 的客户信息全部查询出来,一条一条的查询显然是不可取的,mybatis框架中提供了这样一种语句来进行多条数据查询。那就是<foreach>动态查询语句

 <!-- MyBatis 中已经提供了一种用于数组和集合循环遍历的方式,那就是使用<foreach>元素 
	 <select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
		resultType="org.mybatis.beans.Customer">
		select * from customer where id in
		<foreach item="id" index="index" collection="list" open="(" separator="," close=")">
     	#{id}
		</foreach>
	 </select>
2)<foreach>语句使用分析:

在上述代码中,使用了元素对传入的集合进行遍历并进行了动态SOL组装。关于<foreach>元素中使用的几种属性的描述具体如下。
• item: 配置的是循环中当前的元素。
• index:配置的是当前元素在集合的位置下标。 • collection: 配罩的list 是传递过来的参数类型(首字母小写),它可以是一个array 、list(或collection )、Map 集合的键、POJO 包装类中数组或集合类型的属性名等。
• open 和close:配置的是以什么符号将这些集合元素包装起来。
• separator: 配置的是各个元素的间隔符。

6. <bind>动态查询语句
1) 案例分析

在进行模糊查询编写SO L 语句的时候,如果使用" ${}"进行字符串拼接,则无法防止SOL注入问题;如果使用concat 函数进行拼接,则只针对MySOL 数据库有效,其他数据库则是不同的写法,因此,很不利于项目的移植,为此, MyBatis 提供了<bind>元素来解决这一问题,我们完全不必使用数据库语言,只要使用MyBatis 的语言即可与所需参数连接。

<!-- MyBatis 提供了<bind>元素来解决模糊查询问题,我们完全不必使用数据库语言,
	 	    只要使用MyBatis 的语言即可与所需参数连接。 
	 -->
	 <select id="findcustomerByusername" parameterType="org.mybatis.beans.Customer"
		resultType="org.mybatis.beans.Customer">
		<bind name="p_username" value="'%'+username+'%'"/>	
		select * from customer
		where
		username like #{p_username}
	 </select>
2)<bind>语句使用分析:

上述配置代码中,使用<bind>元素定义了一个name 为pattern_username 的变量, <bind>
元素中value 的属性值就是拼接的查询字符串,在SOL 语句中,直接引用<bind> 元素的name 属性值即可进行动态SOL 组装。

公众号内有更多干货。欢迎关注!

在这里插入图片描述

  • 30
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A-莫天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值