动态SQL

MyBatis基于XML的详细使用——高级结果映射

1、动态sql

动态SQL是MyBatis的强大特性之一。如果你使用过JDBC或其它类似的框架,你应该能理解根据不同条件拱接SQL语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态SQL,可以彻底摆脱这种痛苦。
使用动态SQL并非一件易事,但借助可用于任何SQL映射语句中的强大的动态SQL语言,MyBatis显著地提升了这一特性的易用性。
如果你之前用过JSTL或任何基于类XML语言的文本处理器,你对动态SQL元素可能会感觉似曾相识。在MyBatis之前的版本中,需要花时间了解大量的元素。借助功能强大的基于OGNL的表达式,MyBatis 3替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

  1. if
  2. choose(when,otherwise)
  3. trim(where,set)
  4. foreach
  5. sqlbind
  6. sql片段

if

EmpDao.xml

<!--查询Emp根据id, username ,创建的开始时间和结束时间,
根据部门id如果在编写SQL过程中出现特殊字符报错:1.进行转义
										 2.使用cdata<![CDATA[<=]]>
使用动态SQL:
1.实现动态条件SQL<if
		test条件表达式支持OGNL表达式
问题: and需要动态拼接的问题(只有一个条件的情况就不需要and,如果多个条件就必须用and/or来拼接)
			解决:1.加一个永远都成立的条件(比如: 1=1),后面条件都加上and/or就行
				 2.<where>
				 3.<trim>
<where一般会加载动态条件中配合使用,它会自动在所有条件的前面加上MWHERE关键字,还会去掉所有条件前面的AND/OR
<trim它的功能比较灵活、广泛。它可以用来实现<where节点的功能
		prefix在所有包含的SQL前面加上设置指定的字符串
		prefixOverrides在所有包含的SQL前面加上去除指定的字符串
		suffix在所有包含的SQL后面加上指定的字符串
		suffixOverrides在所有包含的SQL后面加上去除指定的字符串
-->
<select id="QueryEmp" resultType="Emp">
	SELECT * FROM emp
	where 1=1
	<if test="id!=null .and id!=''">
		and id=#{id}
	</if>
	<if test="username!=null and username !='' ">
		and user_name=#t (username}
	</if>
	<if test="beginDate!=null and beginDate!=''">
		and create_date >=# {beginDate}
	</if>
	<if test="endDate!=null and endDate!=''">
		and create_date<![CDATA[<=]]>#{endDate}
	</if>
	<if test="deptId!=null and deptId!=''">
		and dept_id=# {deptId}
	</if>
</select>

choose,when,otherwise

有时候,我们不想使用所有的条件。而只是想从多个条件中选择一个使用,针对这种情况,MyBatis 提供了choose元素,它有点像Java 中的 switch语句 还是上面的例子,但是策略变为:传入了"Tie 就按'tile 查找,传入了"autnor"就按* utho"查找的情形。若两者都没有传入,就返回标记为 fatred的BLOG(这可能是管理员认为,与其返回大量的无意义随机 Blog,还不如返回一些由管理员挑选的Blog)。

<select id="findActiveBlogLike"resultType="Blog">
	SELECT * FROM BLOG WHERE state = ‘ACTIVE'
	<choose>
		<when test="title != null">
			AND title like #{title}
		</when>
		<when test="author != null and author.name != null">
			AND author_name like #{author.name}
		</when>
		<otherwise>
			AND featured = 1
		</otherwise>
	</choose>
</select>

foreach

<!--
<foreach 循环
	实现in 范围查询,使用$可以实现但是有sql注入风险
	collection需要循环的集合的参数名字
	item每次循环使用的接收变量
	separator分割符设置(每次循环在结尾添加什么分隔符,会自动去除最后一个结尾的分隔符)
	open循环开始添加的字符串
	close循环杰中添加的字符目
	index葡环的下标的变量
-->
<select id="QueryEmp3" resultType="Emp">
	SELECT * FROM emp where user_name in
	<where>
		<foreach collection="usernames" item="username" separator="," open="user_name in(" close=")" index="1">
		#{username}
		</foreach>
	</where>
</select>
<!--
<set用在update语句上面的
-->
<update id="update">
	update emp
	<trim prefix="set" suffixOverrides=",">
		<if test="username !=null and username !=’’">
			user_name=# {username},
		</if>
		<if test="createDate!=null and createDate!=''">
			create_date=#{createDate},
		</if>
		<if test="deptId!=null and deptId!=''">
		dept_id=# {deptId}
		</if>
	</trim>
	where id=#{id}
</update>

bind

<!--实现模糊查询 like '%xx%'
可以使用mysql的字符串拼接 1.空格拼接―2.CONCAT函数
2可以拼接好再传进来
3使用bind在Mapper映射文件上下文声明一个变量<bind>
-->
<select id="QueryEmp4" resultType="Emp">
	<bind name="_username" value="'%'+username+'%'"/>
	SELECT* FROM emp where user_name like #{_username}
</select>
<!--
	sql片段解天SQL中重复的代码冗余,可以提取出来放在sql片段中
	1. 〈aq1定义sql月段
	id 唯一标识
	2.<1nclude在SQL中引用SQL片段片段·
	refid 需要引用的SQL片段的id
	'property声明变量,就可以在SQL片段中动态调用,让不同的SQL调用同一个SQL片段达到不同的功能
	name变量名
	value变量值
	一般情况使用$(在sql片段中引用.一单引用了,一定保证每个include都声明了该变圜
-->
<select id="QueryEmp4" resultType="Emp">
	<bind name=" _username" value="'%’+username+'%’"/>
	<include refid"selectEmp></include> 
	where user_name like #{_username}
</select>
<sql id="selectEmp">
	SELECT * FROM emp
</sq1>

script

要在带注解的映射器接口类中使用动态 SQL,可以使用script元素。比如:

@Update({"<script>"",
"update Author",
"<set>",
"<if test= 'username null '>username=#{username} ,</if>",
"<if test='password != null '>password=#{password} ,</if>",
"<if test= ' email != null " >
"email=#{email},</if>",
"<if test='bio != null' >bio=#{bio}</if>",
" </set>",
"where id=#{id}","< / script>"})
void updateAuthorValues(Author author);

MyBatis常用OGNL表达式

 1. e1 or e2
 2. e1 and e2
 3. e1 == e2,e1 eq e2
 4. e1 != e2,e1 neq e2
 5. e1 lt e2:小于
 6. e1 lte e2:小于等于,其他gt(大于),gte (大于等于)
 7. e1 in e2
 8. e1 not in e2
 9. e1 +e2,e1 * e2,e1/e2,e1 - e2,e1%e2
 10.!e, not e:非,求反
 11. e.method( args)调用对象方法
 12.e.property对象属性值
 13.e1[ e2 ]按索引取值,List,数组和Map
 14.@class@method(args)调用类的静态方法
 15.@class@field调用类的静态字段值 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值