【Java EE】动态SQL

动态SQL

概述

MyBatis的动态SQL包括以下几种元素:

元素 作用 备注
if 判断语句 单条件分支判断
choose(when, otherwise) 相当于Java种的switch和case语句 多条件分支判断
trim(where, set) 辅助元素,用于处理特定的SQL拼装问题,比如去掉多余的and、or等 用户处理SQL拼装的问题
foreach 循环语句 在in语句等列举条件常用

if元素

if元素是最常用的判断语句,它常常与test属性联合使用。使用if构建动态SQL语句如下:

<select id="findRole" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role where 1=1
	<if test="roleName!=null and roleName!=''">
		and role_name like concat('%',#{roleName},'%')
	</if>
</select>

choose、when、otherwise元素

在映射器的动态语句种choose、when、otherwise这三个元素承担了多种选择的功能。示例如下:

<select id="findRole" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role 
	where 1=1
	<choose>
	<when test="roleNo!=null and roleNo!=''">
		AND role_no = #{roleNo}
	</when>
	<when test="roleName!=null and roleName !=''">
		AND role_name like concat('%', #{roleName},'%')
	</when>
	<otherwise>
		AND note is not null
	</otherwise>
	</choose>
</select>

trim、where、set元素

加入条件“1=1”是显得很奇快,可以用where元素去处理SQL以达到预期效果。示例如下:

<select id="findRole" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role 
	<where>
	<if test="roleName!=null and roleName!=''">
		AND role_name like concat('%', #{roleName},'%')
	</if>
	<if test="roleName!=null and roleName !=''">
		AND note like concat('%', #{note},'%')
	</if>
	</where>
</select>

当where元素里面的条件成立,才会加入where这个SQL关键字到组装的SQL里面,否则就不加入。
trim元素可以去掉一些特殊的SQL语法,比如常见的and、or等。示例如下:

<select id="findRoles" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role 
	<trim prefix="where" prefixOverride="and">
	<if test="roleName!=null and roleName!=''">
		AND role_name like concat('%', #{roleName},'%')
	</if>
	</trim>
</select>

trim元素意味着要去掉一些特殊的字符串,当prefix代表的是语句的前缀,而prefixOverride代表的是需要去掉哪种字符串。
在MyBatis种,常常可以使用set元素避免发送所有的字段给持久对象。示例如下:

<update id="updateRole" parameterType="role">
	update t_role
	<set>
		<if test="roleName != null and roleName != ''">
			role_name = #{roleName}
		</if>
		<if test = "note != null and note != ''">
			note = #{note}
		</if>
	</set>
</update>

set元素遇到了逗号,它会把对应的逗号去掉。

foreach元素

foreach元素是一个循环语句,他的作用是遍历集合,它能够很好地支持数组和List、Set接口的集合,对此提供遍历功能。它往往用于SQL中的in关键字。示例如下:

<select id ="findUserBySex" resultType="user">
select * from t_role where role_no in 
	<foreach item = "roleNo" index="index" collection="roleNoList" open="("separator="," close=)">
	#{roleNo}
	</foreach>
</select>

其中:

  • collection配置的roleNoList是传递进来的参数名,可以是一个数组、List、Set等集合
  • item配置的是循环中当前的元素
  • index配置的是当前元素在集合的位置下标
  • open和close配置的是以什么符号将这些集合元素包装起来
  • separator是各个元素的间隔符

用test的属性判断字符串

test用于条件判断语句,在MyBatis中使用广泛。示例如下:

<select id="getRoleTest" parameterType="string" resultMap="roleResultMap">
	select role_no, role_name, note from t_role
	<if test="type == 'Y'.toString()">
		where 1=1
	</if>
</select>

如果把type='Y’传递给SQL,就可以发现MyBatis加入了条件where 1=1。

bind元素

bind元素的作用是通过OGNL表达式去自定义一个上下文变量,在进行模糊查询时,如果是MySQL数据库,常常用到的是一个concat,它用"%"和参数相连,如果是Oracle,则用连接符号“||”,这样需要提供两种形式,有了bind元素,就不必使用数据库语言,而是使用MyBatis的动态SQL即可完成。示例如下:

<select id="findRole" parameterType="string" resultMap="com.learn.ssm.mybatis.bean.RoleBean">
	<bind name="pattern" value = "'%'+_parameter+'%'"/>
	select id, role_name as roleName, create_date as createDate, end_date as endDate, end_flag as endFlag, note 
	from t_role where role_name like #{pattern}
</select>

这里的“_parameter”代表传递进来的参数,它和通配符(%)连接后赋给了pattern,然后就可以在select语句中使用这个变量进行模糊查询了。
MyBatis支持多个参数值使用bind元素的用法,传递多个参数前,首先定义接口方法:

public List<RoleBean> findRole(@Param("roleName") String roleName, @Param("note") String note);

定义映射文件和两个新的变量,然后执行模糊查询,如下所示:

<select id="findRole" resultMap="com.learn.ssm.mybatis.bean.RoleBean">
	<bind name="pattern_roleName" value = "'%'+_roleName+'%'"/>
	<bind name="pattern_note" value="'%'+ note + '%'"/>
	select id, role_name as roleName, create_date as createDate, end_date as endDate, end_flag as endFlag, note 
	from t_role where role_name like #{pattern_roleName} and note like #{pattern_note}
</select>

这里绑定了两个新的变量pattern_roleName和pattern_note,这样就可以在SQL的其他地方使用了。

发布了245 篇原创文章 · 获赞 140 · 访问量 26万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章