文章目录
动态SQL
- 基于OGNL(Object-Graph Navigation Language)表达式
- 使用动态SQL完成多条件查询等逻辑实现
- 用于实现动态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