动态SQL

前言

动态SQL是MyBatis强大的特性,在使用JDBC操作数据的时候,如果查询的条件特别多,将SQL语句连成字符串是一件很痛苦的事情,通常我们用if-else进行拼接。MyBatis使用动态SQL语言来改善这种情形。

用于实现动态SQL元素如下

基于OGNL表达式
完成多条件查询等逻辑实现
用于实现动态SQL的元素主要有

  • if:实现简单是条件选择
  • trim:灵活的去除多余的关键字
  • where:简化SQL语句中的where条件判断
  • choose(when、otherwise):相当于Java中的switch语句,通常when与otherwise搭配
  • foreach:迭代一个结合,通常用于 in条件
  • set:解决动态SQL语句。
使用if-where实现多条件查询
1. if

if就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。
当我们多条件查询的时候,多有的条件都不能为空,但是我们要查询的因素不固定,若果查询条件为空的话,查不出我们想要的结果。

<select id="getBiilList" resultType="Bill">
		SELECT b.*, p.proName as providerName FROM smbms_bill  b,smbms_provider p 0 
			WHERE b.id=p.id
			<if test="productName!=null and productName!=''">
				 AND b.productName LIKE  CONCAT ('%', #{productName}, '%') 	
			</if>
			<if test="providerId!=null">
				 AND b.providerId=#{providerId}	
			</if>
			<if test="isPayment!=null">
				 AND b.isPayment=#{isPayment}
			</if>
	</select>
2. where

where元素的作用是会在写入where元素的地方输出一个where,另外一个

好处是你不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智

能的处理,如果所有的条件都不满足那么MyBatis就会查出所有的记录,如果

输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,

MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,

MyBatis会智能的帮你加上。像上述例子中,如果title=null, 而content != null,

那么输出的整个语句会是select * from t_blog where content = #{content},而

不是select * from t_blog where and content = #{content},因为MyBatis会智

能的把首个and 或 or 给忽略。

<select id="getProvider" resultType="Provider">
		SELECT * FROM smbms_provider 
		<where>
			<if test="proCode!=null and proCode!=''">
				and proCode like CONCAT ('%',#{proCode},'%') 
			</if>
			<if test="proName!=null and proName!=''">
				and proName like CONCAT ('%',#{proName},'%') 
			</if>
		</where>
	</select>
使用if-trim实现多条件查询
1. trim

属性

  • prefix:前缀,作用通过自动识别是否有返回值后,在trim包含的内容上前缀,如此处的where。
  • suffix:后缀,作用是在trim包含的内容上加上后缀。
  • prefixOverrides:对于trim包含内容的首部进行制定内容(如此处的and || or) 的忽略。
  • suffixOverrides:对于trim包含内容的首尾部进行指定内容的忽略。

作用:我们可以用if-trim代替if-where

使用动态SQL实现更新操作

使用if+set改造跟新操作

问题:我们为什么要使用if+set完成更新操作哪?

当修改数据库的时候,执行操作的时候,每个字段都进行了赋值更新。在实际中我们不会每次把数据全部跟新一遍,只会修改用户要修改的字段,对于用户没修改的数据,数据库不会进行相应的修改操作。

set元素主要用于跟新操作,它的主要功能和where差不多,主要包含的语句首输出一个set,若包含语句中是以 ,(逗号) 结尾的,会自动把逗号忽略掉,在配合if元素就可以动态的跟新需要修改的字段,而不需要修改的字段,则可以不被更新。

<update id="updProvider" parameterType="Provider">
		update smbms_provider 
		<set>
			<if test="proCode!=null">proCode=#{proCode},</if>
			<if test="proName!=null">proName=#{proName},</if>
			<if test="proDesc!=null">proDesc=#{proDesc},</if>
			<if test="proContact!=null">proContact=#{proContact},</if>
			<if test="proPhone!=null">proPhone=#{proPhone},</if>
			<if test="proAddress!=null">proAddress=#{proAddress},</if>
			<if test="proFax!=null">proFax=#{proFax},</if>
			<if test="modifyBy!=null">modifyBy=#{modifyBy},</if>
			<if test="modifyDate!=null">modifyDate=#{modifyDate}</if>
		
		</set>
		 where id = #{id}
	</update>
使用if+trim改造修改操作

我们可以使用trim元素代替set元素,并且可以实现相同的操作。

<update id="updProvider1" parameterType="Provider">
		update smbms_provider 
		<trim prefix="set" suffix="where id = #{id}" suffixOverrides=",">
			<if test="proCode!=null">proCode=#{proCode},</if>
			<if test="proName!=null">proName=#{proName},</if>
			<if test="proDesc!=null">proDesc=#{proDesc},</if>
			<if test="proContact!=null">proContact=#{proContact},</if>
			<if test="proPhone!=null">proPhone=#{proPhone},</if>
			<if test="proAddress!=null">proAddress=#{proAddress},</if>
			<if test="proFax!=null">proFax=#{proFax},</if>
			<if test="modifyBy!=null">modifyBy=#{modifyBy},</if>
			<if test="modifyDate!=null">modifyDate=#{modifyDate}</if>
		
		</trim>
		 
	</update>

使用foreach完成复杂查询

foreach基本属性
  • item:表示集合中每一个元素进行迭代时的别名。
  • index:指定一个名称,用于表示在迭代过程中,每次迭代的位置。
  • open:表示该语句以什么开始(既然是 in 条件语句所以必然以(开始)
  • separator:每次迭代之间以什么符号作为分割符(既然是 in 条件语句,所以必然是以 作为分隔符。)
  • close:表示该语句以什么结尾。(既然是 in 必然是以结尾)。
  • collection:最关键最容易出错的属性,需要格外注意,主要有三种情况。
    (1) 若入参为单参数且参数类型为List的时候,collection属性为list
    (2)若入参为单参数且参数类型为数组的时候,collection属性为array
    (3)若传入的参数为多参数,就需要把它封装成Map进行处理。
MyBatis入参为数组类型的foreach迭代
<select id="getBillByProviderIdArray" resultMap="billMapByProIds" >
		SELECT * FROM smbms_bill WHERE providerId IN
		<foreach collection="array" item="bill" open="(" separator="," close=")">
			#{bill}
		</foreach>
	
	</select>
MyBatis入参为List类型的foreach迭代
<select id="getBillByProviderIdList" resultMap="billMapByProIds" >
		SELECT * FROM smbms_bill WHERE providerId IN
		<foreach collection="list" item="bill" open="(" separator="," close=")">
			#{bill}
		</foreach>
	
	</select>
MyBatis入参为Map类型的foreach迭代
<select id="getBillByProviderIdMap" resultMap="billMapByProIds" >
		SELECT * FROM smbms_bill WHERE billCode like CONCAT ('%',#{billCode},'%') AND providerId IN
		<foreach collection="providerIds" item="bill" open="(" separator="," close=")">
			#{bill}
		</foreach>
	
	</select>
choose(when,otherwise)

相当于Java中的Switch

<select id="getProviderList" resultType="Provider">
		select * from smbms_provider where 1=1
			<choose>
				<when test="proCode!=null and proCode!=''">
					and proCode like CONCAT ('%',#{proCode},'%') 
				</when>
				<when test="proName!=null and proName!=''">
					and proName like CONCAT ('%',#{proName},'%') 
				</when>
				<when test="proContact!=null and proContact!=''">
					and proContact like CONCAT ('%',#{proContact},'%') 
				</when>
				<otherwise>
					and creationDate like CONCAT ('%',#{creationDate},'%') 
				</otherwise>
			</choose>
	</select>

MyBatis实现分页功能

MyBatis分页

主要基于内存分页的,查出所有的数据,在按其实位置,和页面容量分页

  • 分页-DAO层实现
    limit(起始位置,页面容量)
  • 查询用户列表的方法增加2个参数
    from
    pageSize

总结

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值