MyBatis之动态SQL(最近在整理一些知识点,想学习的同志们,可以关注我的博客,MyBatis之后是Spring框架)

动态SQL

  1. 基于OGNL(Object-Graph Navigation Language)表达式
  2. 使用动态SQL完成多条件查询等逻辑实现
  3. 用于实现动态SQL的元素主要有
    if 简单地条件选择
    trim 灵活去除多余的关键字
    where 简化where的条件判断
    set
    choose(when、otherwise)
    foreach

动态SQL示例1(多条件查询):

原始代码:

<!-- 查询用户列表(连表查询) -->
	<select id="getUserList" resultMap="userList" >
		select u.*,r.roleName from smbms_user u,smbms_role r 
			where userName like CONCAT('%',#{userName},'%')
				and userRole = #{userRole} and u.userRole = r.id
	</select>

从上面的代码中可以看出来,只有传入两个条件的时候即(userName 和 userRole都传入)这可语句才会成功运行,但是实际操作的过程中,查询只需要一个条件时,就得在写一个语句。而动态SQL就提供了可选择的功能

优化代码:

(1)if

if(test="(添加的是一个if条件)">

<!-- 查询用户列表(连表查询) -->
	<select id="getUserList" resultMap="userList" >
		select u.*,r.roleName from smbms_user u,smbms_role r 
			where u.userRole = r.id
			<if test="userRole != null">
			and userRole = #{userRole}
			</if>
			<if test="userName != null and userName != '' ">
			and userName like CONCAT('%',#{userName},'%')
			</if>
	</select>

(2)where:

			简化SQL语句中where条件判断
			智能化的处理【and】和【or】

查询的时候,当出现有一个条件两个条件只有一个添加了数据时,会出现,and 对于的情况,如下图:在这里插入图片描述

报的错误是:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'and userName like CONCAT('%','å­™','%')' at line 4

所以有进行优化(避免了出现SQL语法错误问题)【and 多余的会自动剔除】:

<!-- 查询用户列表(连表查询) -->
	<select id="getUserList" resultMap="userList" >
		select u.* from smbms_user u
		<where>
			<if test="userRole != null">
			and userRole = #{userRole}
			</if>
			<if test="userName != null and userName != '' ">
			and userName like CONCAT('%',#{userName},'%')
			</if>
		</where>
	</select>

(3)trim:

			属性
				prefix    前缀添加内容
				suffix	后缀添加内容
				prefixOverrides	前缀覆盖
				suffixOverrides	后缀覆盖
			更灵活的去除多余关键字
			替代where
<!-- 查询用户列表(连表查询) -->
	<select id="getUserList" resultType="user" >
		select u.* from smbms_user u 
		<trim prefix="where" prefixOverrides="and / or">
			<if test="userName != null and userName != '' ">
			 userName like CONCAT('%',#{userName},'%')
			</if>
			<if test="userRole != null">
			 userRole = #{userRole}
			</if>
		</trim>

注意: 将if结构中的and 去掉

示例2(修改信息):

要求:当修改的信息为空时,维持原有的信息不变

<!--修改操作  -->
	<update id="modify" parameterType="user">
		update smbms_user set userCode = #{userCode},userName = #{userName} ,userPassword = #{userPassword},
				gender=#{gender}, birthday = #{birthday} ,phone=#{phone} ,address=#{address},userRole =#{userRole},
				modifyBy =#{modifyBy},modifyDate = #{modifyDate}
				 where id = #{id}
	</update>

(1)if+set(实际的应用比较少)

<!--修改操作  -->
	<update id="modify" parameterType="user">
		update smbms_user
		<set>
			<if test="userCode">userCode = #{userCode}</if>	
			<if test="userName">userName = #{userName}</if>	
			<if test="userPassword">userCode = #{userCode}</if>	
			<if test="userCode">gender=#{gender}</if>	
			<if test="userCode">birthday = #{birthday}</if>	
			<if test="userCode">phone=#{phone}</if>	
			<if test="userCode">address=#{address}</if>	
			<if test="userCode">userRole =#{userRole}</if>	
			<if test="userCode">modifyBy =#{modifyBy}</if>	
			<if test="userCode">modifyDate = #{modifyDate}</if>	
		</set>
				 where id = #{id}
	</update>

(2)使用 if+trim代替if+set

<!--修改操作  -->
<update id="modify" parameterType="user">
		update smbms_user
		<trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
			<if test="userCode != null">userCode = #{userCode},</if>	
			<if test="userName!= null">userName = #{userName},</if>	
			<if test="userPassword != null">userCode = #{userCode},</if>	
			<if test="gender != null">gender=#{gender},</if>	
			<if test="birthday != null">birthday = #{birthday},</if>	
			<if test="phone != null">phone=#{phone},</if>	
			<if test="address != null">address=#{address},</if>	
			<if test="userRole != null">userRole =#{userRole},</if>	
			<if test="modifyBy != null">modifyBy =#{modifyBy},</if>	
			<if test="modifyDate != null">modifyDate = #{modifyDate},</if>	
		</trim>
	</update>

示例3(指定用户角色,获取用户列表信息)

(1)foreach

迭代一个集合,通常用于in条件
属性
	item
	index
	collection:必须指定
			-list
			-array
			-map-key
	open	开始位置
	separator		中间隔开
	close	结尾位置
select * from smbms_user where userRole in (var 1,var 2,var 3...);

传入的类型为 array
【一般情况下,不使用Param的注解方式。而是使用默认值:list或array】

<resultMap type="User" id="userMapRole">
		<id property="id" column="id"/>
		<result property="userCode" column="userCode"/>
		<result property="userName" column="userName"/>
	</resultMap>
	<select id="getUserRoleId_foreach_array" resultMap="userMapRole">
		select * from smbms_user where userRole in
		<foreach collection="array" item ="roleIds" open="(" separator="," close=")">
			#{roleIds}
		</foreach>

示例4(在示例三的基础上增加一个额外的参数:gender,要求查出指定性别和用户连角色列表下的用户列表)

使用了map集合

<resultMap type="User" id="userMapRole">
		<id property="id" column="id"/>
		<result property="userCode" column="userCode"/>
		<result property="userName" column="userName"/>
	</resultMap>
<select id="getUserByConditionMap_foreach_map" resultMap="userMapRole">
		select * from smbms_user where gender=#{gender} and userRole in 
		<foreach collection="roleIds" item="roleMap" open="(" separator="," close=")">
		
		#{roleMap}</foreach>
	</select>

(2)choose(when、otherwise)

相当于java中的switch语句
当when有条件满足的时候,就跳出choose
<choose>
	<when test="条件1">...</when>
	<when test="条件2">...</when>
	<when test="条件3">...</when>
	...
	<otherwise>...</otherwise>
</choose>

MyBatis接收的参数类型

基本数据类型:key值:变量名 value值:变量值
数组:key值:“array” value值:该数组
对象:key值:对象的属性名 value值:对象的属性值
Map:key值:键名 value值:键值
List:key值:“list” value值:该list

无论入参何种数据类型,MyBatis都会将其放入在一个Map中

原创文章 28 获赞 41 访问量 1032

猜你喜欢

转载自blog.csdn.net/wenquan19960602/article/details/104355906