MyBatis动态SQL

目录

1、动态SQL

(1)什么是动态SQL?

(2)常用的动态SQL元素

2、if元素

[3、choose 、when 、otherwise元素](#3、choose 、when 、otherwise元素)

(1)为什么使用choose元素

(2)choose元素的功能

[4、trim 、where 、set 元素](#4、trim 、where 、set 元素)

(1)什么是where元素

(2)什么是set元素

(3)什么是trim元素

5、foreach元素

(1)什么是foreach元素

6、bind元素

(1)什么是bind元素


1、动态SQL

打个比方说,我们在网站上查询一个手机,他会有很多的选项,比如品牌、内存、处理器、年份等等。这就好比我们sql语句中的查询操作,select * from 手机表 where 品牌 and 内存 and 处理器 等等。但是在我们用MyBaits写映射器处理sql语句时是固定的查询,这就导致我们的代码是硬代码。就好比下方代码:

XML 复制代码
<select id = "findStudentByClassidAndSsex" parameterType="student" resultType="student">
	select * from student where classid = #{classid} and ssex = #{ssex}
</select>

这里就只能查询规定班级号和性别的学生,但是如果我想要通过学生id查看或者通过学生生日查询的话就还得再去写新的映射器,这样就会造成代码冗余。

(1)什么是动态SQL?

定义:根据不同条件拼接SQL语句,实现对数据库更准确的操作;

实现:映射器配置文件或者注解。

(2)常用的动态SQL元素

|--------------------------|-------------------------|
| if 元素 | 判断语句,单条件分支判断. |
| choose元素(when,otherwise) | 多条件分支判断,等同于java的switch. |
| trim(where,set) | 辅助元素,用于处理一些 SQL 拼接的问题. |
| foreach 元素 | 循环语句,在 in 语句等列举条件常用 |

2、if元素

语法: < if test ="条件"> 满足条件的语句

注意:拼接 SQL 语句的时候注意 AND 和逗号

示例代码:

XML 复制代码
<select id = "findStudent" parameterType="student" resultType="student">
	select * from student where 1=1
	<if test="classid != 0">
		and classid = #{classid}
	</if>
		
	<if test="ssex != null">
		and ssex = #{ssex}
	</if>
</select>

可以添加多条if来实现动态查询,加上一个if就会多一层判断。

3、choose 、when 、otherwise元素

(1)为什么使用choose元素

choose相当于java中 switch 结构,条件有先后顺序,越优先先写,一旦匹配到,后面的条件就不会再执行。

场景1:当新闻编号不为空,则只用新闻编号作为查询条件;

场景2:当新闻编号为空,而新闻标题不为空,则用新闻标题作为条件进行模糊查询;

场景3:当新闻编号和新闻标题都为空,则要求新闻作者不能为空。

(2)choose元素的功能

语法:

XML 复制代码
<choose> 
    <when test="条件">满足条件的语句</ when>
    <otherwise> 满足其他条件的语句 <otherwise>
</choose>

注意:

  • 拼接 SQL 语句的时候注意 AND 和逗号
  • when 标签自带break
  • otherwise 标签当所有的when都不匹配时才会执行,相当于 default、else 可以不写。

4、trim 、where 、set 元素

前言:if语句中如果没有匹配上的话就拼接后的sql语句就变成了select * from 表名 where了。

所以就有了trim、where、set元素的出现。

(1)什么是where元素

示例代码:

XML 复制代码
<select id = "findStudentWhere" parameterType="student" resultType="student">
	<include refid="stusql"></include>
	<where>
		<if test="classid != 0">
		    and classid = #{classid}
		</if>
			
		<if test="ssex != null">
			and ssex = #{ssex}
		</if>
	</where>
</select>

注意:当前没有任何条件的时候,不会添加where关键字 有条件的时候会添加一个where关键字、去掉第一个and关键字。

(2)什么是set元素

示例代码:

XML 复制代码
<update id="updateStudentSet" parameterType="student">
	update student
	<set>
		<if test="sname != null">
			sname = #{sname},
		</if>
			
		<if test="birthday != null">
			birthday = #{birthday},
		</if>
			
		<if test="ssex != null">
			ssex = #{ssex},
		</if>
			
		<if test="classid != null">
			classid = #{classid},
		</if>
	</set>
	<where>
		sid = #{sid}
	</where>
</update>

相当于sql语句添加set关键字,而且会去掉最后一个逗号。

(3)什么是trim元素

前言:where子句的 and 和 or、set 子句的逗号,就算set能去除逗号,呢也是最后一个逗号,前面的语句中的逗号也十分的难缠,这时候我们就可以用trim万能标签来解决这一问题。

  • prefix:需要往前拼接的子句,可以是 where,or 或者 set;(开始前添加一个什么)
  • suffix:需要往后拼接的子句,可以是 where,or 或者 set;(结束后添加一个什么)
  • suffixOvrrides:忽略通过管道分隔的文本序列后缀。一般不与 prefixOvrrides 同时使用。(结束后去掉一个什么)
  • prefixOvrrides:忽略通过管道分隔的文本序列前缀。一般不与 suffixOvrrides 同时使用。(开始前去掉一个什么)

示例代码:

XML 复制代码
<update id="updateStudentTrim" parameterType="student">
 	update student 
 	<trim prefix="set" suffixOverrides=",">
 		<if test="sname != null">
			sname=#{sname},
		</if>
		<if test="birthday != null">
			birthday=#{birthday},
		</if>
		<if test="ssex != null">
			ssex=#{ssex},
		</if>
		<if test="classid != 0">
			classid=#{classid},
		</if>
 	</trim>
 	<trim prefix="where" prefixOverrides="and">
 		and sid = #{sid}
 	</trim>
</update>

5、foreach元素

前言:

如果sql语句中的条件判断太多太复杂,呢这时候有没有一个公式可以让我们拼接呢。 这时候就可以用foreach元素来拼接。

(1)什么是foreach元素

|------------|---------------------|
| item | 循环中的当前元素; |
| index | 当前循环元素的位置下标; |
| collection | 方法传递的参数,一个数组或者集合; |
| open | 以什么符号开始将这些集合元素包装起来; |
| close | 以什么符号结束将这些集合元素包装起来; |
| separator | 各个元素的间隔符号。 |

示例代码: (clollection 如果是数组传array,如果List结合传list)

array数组:

XML 复制代码
<select id="findStudentArray" resultType="student" >
 	 <include refid="stusql"/>
 	 <where>
 	     <foreach collection="array" item="x" open="sid in (" close=")"             separator=",">
 	 			#{x}
 	 	 </foreach>
 	 </where>
</select>

list列表:

XML 复制代码
<select id="findStudentList" resultType="student" >
 	 <include refid="stusql"/>
 	 <where>
 	 	<foreach collection="list" item="x" open="sid in (" close=")" separator=",">
 	 		#{x}
 	 	</foreach>
 	 </where>
</select>

6、bind元素

前言:

通配符比如模糊查询会给SQL语句拼接增加难度,因为拼接中的%号为字符串。 呢bind元素就可以解决这个问题。

(1)什么是bind元素
  • name:自定义变量的变量名。
  • value:自定义变量的变量值。
  • _parameter:传递进来的参数。

解决模糊查询:

方案一(concat()拼接):

XML 复制代码
select * from student where sname like concat('%',#{value},'%')

方案二(sql语法):

XML 复制代码
select * from student where sname like "%"#{value}"%"

方案三(${}不推荐):

XML 复制代码
select * from student where sname like ${%}#{value}${%}

${} 字符串的替换 不能防止SQL注入

方案四(bind强烈推荐):

XML 复制代码
<bind name="keyn" value="'%'+_parameter+'%'"/>
select * from student where sname like #{keyn}

注意:bind是用来定义变量。

相关推荐
清水白石0083 分钟前
从一个“支付状态不一致“的bug,看大型分布式系统的“隐藏杀机“
java·数据库·bug
Python私教5 小时前
model中能定义字段声明不存储到数据库吗
数据库·oracle
弗拉唐6 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
mqiqe7 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
工业甲酰苯胺7 小时前
MySQL 主从复制之多线程复制
android·mysql·adb
BestandW1shEs7 小时前
谈谈Mysql的常见基础问题
数据库·mysql
重生之Java开发工程师7 小时前
MySQL中的CAST类型转换函数
数据库·sql·mysql
教练、我想打篮球7 小时前
66 mysql 的 表自增长锁
数据库·mysql
Ljw...7 小时前
表的操作(MySQL)
数据库·mysql·表的操作