1, MyBatis动态SQL

  • 动态SQL是MyBatis框架中特性之一,在一些组合查询页面需要根据用户输入的条件不同生成不同的查询SQL语句,在JDBC或其他相似框架中需要在代码中拼接SQL语句,容易出错。MyBatis动态SQL可以解决这种问题。

动态SQL标签与JSTL标签相似,它允许在xml中构建不同的SQL语句,常用SQL标签:

  • 判断标签: ifchoose(when,otherwise)
  • 关键字标签: wheresettrim
  • 循环标签: foreach

1.1 if 标签

  • if标签是简单条件判断逻辑,满足指定条件时追加if标签内的sql语句,不满足时不增加。
<select>
		sql语句1
	<if test="条件表达式">
		sql语句2
	</if>
</select>
  • if 标签最常见的使用是在where字句部分,根据不同的条件追加不同的SQL语句。

1.2 choose 标签

  • choose 标签的作用相当于Java 的 switch 语句,和JSTL中的choose标签作用和用法一致,通常与when和otherwise搭配使用。
<select>
		sql语句1
	<choose>
		<when test="条件表达式">
			sql语句2
		</when>
		<when test="条件表达式">
			sql语句3
		</when>
		<otherwise>
			sql语句4
		</otherwise>
	</choose>
</select>

1.3 where 标签

  • where 标签可以在 <where> 标签所在的位置输出一个where关键字,而且可以将后面多余的 and 或者 or 关键字去除
	<select>
		select * from emp 
		<where>
			<if test="deptno!=null">
				deptno=#{deptno}
			</if>
			<if test="salary!=null">
				and salary=#{salary}
			</if>
		</where>
	</select>

1.4 set 标签

  • set 标签主要用在更新操作时,功能和where标签相似,在 <set> 标签所在的位置输出一个set 关键字,可以去除与内容结尾无关的逗号。
	<update>
		update emp 
		<set>
			<if test="empno!=null">
				where empno=#{empno},
			</if>
			<if test="deptno!=null">
			where deptno=#{deptno},
			</if>
		</set>
		<if test="empno!=null">
			where empno=#{empno}
		</if>
	</update>

1.5 trim 标签主要功能:

  • 可以在自己包含的内容前面(或者后面)加上某些前缀,与之对应的属性是 prefixsuffix
  • 可以把包含内容前或者后的某些内容过滤,即忽略,对应的属性是 prefixOverridessuffixOverrides
	<!-- 等价于where标签 -->
<!-- 忽略语句前的 "and" 和 "or" -->
	<trim prefix="where" prefixOverrides="and | or">
		...
	</trim>
	<!-- 等价于set标签 -->
<!-- 忽略语句后的 "," -->
	<trim prefix="set" suffixOverrides=",">
		...
	</trim>

1.6 foreach 标签

  • foreach 标签实现循环逻辑,可以进行一个集合迭代,主要用在构建IN条件中
<!-- select * from emp where empno in (1001.1003.1005); -->
		<select>
			select * from emp where empno in
			<foreach collection="集合" item="迭代变量" open="(" close=")" separator="间隔符(一般是',')">
				#{迭代变量}
			</foreach>
		</select>
<!-- insert into dept values( 1 ,"研发部"),( 2 ,"财务部"),( 3 ,"市场部"); -->
		<insert> 
			insert into dept values
			<foreach collection="depts" item="dept" separator=",">
				(#{dept.deptno},#{dept.dname})
			</foreach>
		</insert>
  • foreach 标签它允许指定一个集合,声明集合项和索引变量,变量可以用在标签体内,它允许指定开放和关闭的字符串,在迭代项之间放置分隔符。

1.7 bind 标签

  • bind 标签可以从OGNL表达式中创建一个变量,并将其绑定到上下文。

mapper.xml 中字符串拼接:

  • 使用连接函数
select * from emp where ename like concat('%',#{ename},'%')
  • 使用build标签
	<select id="findByEname" parameterType="Condition" resultType="Emp">
		<bind name="emp_ename" value="'%'+ename+'%'"/>
			select * from emp where ename like #{emp_ename}
	</select>

1.8 注意:

  • 在Oracle数据库中concat函数有且仅有两个参数,若有多个字符串需要拼接,则需要嵌套调用concat()函数。
  • 如:concat(caoncat(‘’,‘’))
  • 在xml中特殊符号需要转义。
    采用xml转义字符进行转义(分号不能丢)
    < -----> &lt;
    > -----> &gt;
    & -----> &amp;
    ’ -----> &apos;
    " -----> &quou;
    空格 -----> &nbsp;
  • 采用 <![CDATA[]]> 进行说明,将此内容不进行解析。
<if test="salary !=null">
	<choose>
		<when test="salary>50000">
			where salary <![CDATA[>]]> #{salary}
		</when>
加粗样式	<	when test="salary>40000">
		where salary > #{salary}
		</when>
			<otherwise>
				where salary  <![CDATA[<]]> 40000
			</otherwise>
	</choose>
</if>

1.9 #{} 与 ${}取值比较

  • 都是取变量的值
  • #{}在取值时,sql语句中变量值会替换成“”,${} 直接替换成变量的值,因此**#{}** 处理时安全的,可以防止SQL注入,且sql是预编译的。
  • ${} 方式一般用于传入数据对象,例如:表名,字段名。
例如:
	select * from emp where empno=#{id}
	select * from emp where empno=${id}
若id参数的值是1001, 则分别解析为:
	#{}:	select * from emp where empno='1001'
	${}:	select * from emp where empno=1001
若参数是"'empno=1001'or'1=1'",则分别解析为:
	#{}:	"'empno=1001'or'1=1'"
	${}: 	'empno=1001'or'1=1'	
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐