mybatis中动态sql标签的用法

本章节主要介绍mybatis的动态sql的作用和用法

 

一、mybatis动态SQL概述

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。

动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。

二、mybatis动态SQL标签

动态sql元素
标签作用备注
if判断语句单条件分支判断
choose(when、otherwise)相当于java中带return的switch和catch语句多条件分之判断
trim(where、set)辅助元素,用于处理特定的sql拼装问题,比如去除多余的and、or、, 等用于处理sql拼装问题
foeach循环语句在in语句等列举条件常用

 

动态sql实际使用的标签并不多,但是却可以带来极大的灵活性,很大程度上提高的程序的可读性和可维护性。

1、if标签

if标签会对test中的表达式做判断,如果表达式成立就执行if标签中的sql语句,如果不成立就不执行。

test中的表达式采用OGNL表达式的方式,可以对参数取值判断

<!--
	if test:判断表达式(OGNL)从参数中取值进行判断
	如果表达式中包含&& "" 等需要进行特殊字符的转义
 -->
<select id="getEmpIf" resultMap="employee">
	SELECT id,last_name,email,gender
	FROM tbl_employee
	WHERE 1=1
	<if test="lastName != null">
		AND last_Name = #{lastName}
	</if>
	<if test="department != null and department.id != null">
		AND dept_id = #{department.id}
	</if>
</select>

2、choose(when、otherwise)标签

有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句

​
<select id="getEmpsByConditionChoose" resultType="com.wcg.mybatis.entity.Employee">
	select * from tbl_employee
	<where>
		<!-- 如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个 -->
		<choose>
			<when test="id!=null">
				id=#{id}
			</when>
			<when test="lastName!=null">
				last_name like #{lastName}
			</when>
			<when test="email!=null">
				email = #{email}
			</when>
			<otherwise>
				gender = 0
			</otherwise>
		</choose>
	</where>
</select>

​

3、trim、where、set标签

如果在where条件中只使用if标签可能会导致一些SQL语法错误(并没有像上面讲述的if标签时,加入条件1=1):

<select id="getEmpIf" resultMap="employee">
	SELECT id,last_name,email,gender
	FROM tbl_employee
	WHERE
	<if test="lastName != null">
		AND last_Name = #{lastName}
	</if>
	<if test="department != null and department.id != null">
		AND dept_id = #{department.id}
	</if>
</select>

如果上面这些条件没有一个能匹配上会发生什么?最终这条 SQL 会变成这样:

SELECT id,last_name,email,gender 
FROM tbl_employee WHERE

如果仅仅第二个条件匹配又会怎样?这条 SQL 最终会是这样: :

SELECT id,last_name,email,gender 
FROM tbl_employee 
WHERE AND dept_id = #{department.id}

where标签

这时候就可以使用where标签:where 标签只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。

<select id="getEmpsByConditionWhere" resultMap="employee">
    SELECT * FROM BLOG
    <where>
        <if test="lastName != null">
            AND last_Name = #{lastName}
        </if>
        <if test="department != null and department.id != null">
            AND dept_id = #{department.id}
        </if>
    </where>
</select>

set标签

set 标签会动态前置 SET 关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。(注意:因为用的是“if”元素,若最后一个“if”没有匹配上而前面的匹配上,SQL 语句的最后就会有一个逗号遗留)

<update id="updateEmp">
	<!-- Set标签的使用 -->
	update tbl_employee
	<set>
		<if test="lastName!=null">
			last_name=#{lastName},
		</if>
		<if test="email!=null">
			email=#{email},
		</if>
		<if test="gender!=null">
			gender=#{gender}
		</if>
	</set>
	where id=#{id}
</update>

trim标签

在上面讲述的where标签和set标签中,都是可以使用trim标签替代而且功能更强大

例如:后面多出的and或者or where标签不能解决

trim标签属性
属性作用
 prefix前缀: prefix给拼串后的整个字符串加一个前缀
prefixOverrides前缀覆盖: 去掉整个字符串前面多余的字符
suffix后缀 :suffix给拼串后的整个字符串加一个后缀
suffixOverrides后缀覆盖: 去掉整个字符串后面多余的字符

使用trim替代where:

<select id="getEmpsByConditionTrim" resultMap="employee">
	select id,last_name,email,gender from tbl_employee
	
	<!-- 自定义字符串的截取规则 -->
	<trim prefix="where" suffixOverrides="AND">
        <if test="lastName != null">
            AND last_Name = #{lastName}
        </if>
        <if test="department != null and department.id != null">
            AND dept_id = #{department.id}
        </if>
	</trim>
</select>

使用trim替代set:

<update id="updateEmp">
	<!-- Set标签的使用 -->
	update tbl_employee
	<trim prefix="set" suffixOverrides=",">
		<if test="lastName!=null">
			last_name=#{lastName},
		</if>
		<if test="email!=null">
			email=#{email},
		</if>
		<if test="gender!=null">
			gender=#{gender}
		</if>
	</trim>
	where id=#{id}
</update>

4.foreach标签

foreach元素是一个循环语句,它的作用是遍历集合,它能够很好地对数组和list、set接口的集合提供遍历的功能

foreach标签的属性
属性作用
collection指定需要遍历的集合
item将当前遍历出的元素赋值给指定的变量
separator每个元素的分隔符
open遍历出所有结果拼接的开始字符
close遍历出所有结果拼接的结束字符
index索引:遍历list的时候是index就是索引,item就是当前值
          遍历map的时候index表示的就是map的key,item就是map的值
<select id="getEmpsByConditionForeach" resultMap="employee">
	select * from tbl_employee
	<!--
		#{变量名}就能取出变量的值也就是当前遍历出的元素
	  -->
	<foreach collection="ids" item="item_id" separator=","
			 open="where id in(" close=")">
		#{item_id}
	</foreach>
</select>

 

三、额外说明

除了上述的一些动态标签,映射器中海油一些其它的标签:

1、bind标签

bind标签的作用是通过OGNL表达式去定义一个上下文变量,方便使用时去引用。比如在使用模糊查询的时候,使用#{}进行预编译处理,则必须在传参的时候就带上%或者_来进行模糊查询,因为如果在sql语句中拼接会报错。这时候就可以使用bind来解决

<select id="getEmpsTestInnerParameter" resultMap="employee">
	<!-- bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值 -->
	<bind name="_lastName" value="'%'+lastName+'%'"/>
	select * from tbl_employee
	<if test="_parameter!=null">
		where last_name like #{lastName}
	</if>
</select>

2、sql标签

sql标签的作用是可以定义一条sql的一部分,在使用的时候可以进行引用,常用的方式是定义列名。在编写select、insert等语句的经常要反复的编写列名,这时候就可以直接进行引用

注:

1、sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用
2、include来引用已经抽取的sql:
3、include还可以自定义一些property,sql标签内部就能使用自定义的属性
                  include-property:取值的正确方式${prop},
                  #{不能使用这种方式}

<sql id="employeeColumn">
	id,last_name,email,gender
</sql>

<select id="getAllEmp" resultMap="employee">
	SELECT 
	<include refid="employeeColumn"></include>
	FROM tbl_employee
</select>

3、映射器中的两个内置参数

mybatis默认还有两个内置参数:

  •          _parameter: 代表整个参数

             单个参数:_parameter就是这个参数
             多个参数:参数会被封装为一个map;_parameter就是代表这个map

  •          _databaseId:如果配置了databaseIdProvider标签。

             _databaseId就是代表当前数据库的别名mysql

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值