动态 SQL(1)
使用动态 SQL 完成多条件查询
动态 SQL 是 MyBatis 的一个强大的特性。在使用 JDBC 操作数据时,如果查询条件特别多,将条件串联成 SQL 字符串是一件痛苦的事情,通常的解决方法是写很多的 if-else 条件语句对字符串进行拼接,并确保不能忘了空格或在字段的最后省略逗号。 MyBatis 使用一种强大的动态 SQL 语言来改善这种情形。动态 SQL 基于 OGNL 的表达式,可使我们方便地在 SQL 语句中实现某些逻辑。
  用于实现动态 SQL 的元素如下:
      ➣ if:利用 if 实现简单的条件选择。
➣ choose(when,otherwise):相当于 Java 中的 switch 语句,通常与 when 和 otherwise 搭配。
➣ where:简化 SQL 语句中 where 的条件判断。
➣ set:解决动态更新语句。
➣ trim:可以灵活地去除多余的关键字。
➣ foreach:迭代一个集合,通常用于 in 条件。
说明:由于在进行多条件查询的时候,用户并不一定会完整地输入所有的查询条件,因此对于此类情况,要使用 MyBatis 的动态 SQL 来实现多条件查询。
 if 元素
<!--test 属性:表示进入 if 内需要满足的条件-->
<if test="" >
<!--if 条件满足时执行的内容-->
</if> <!-- 根据用户名称(模糊查询)和用户角色查询用户列表(要求用户角色要显示角色名称而不是角色 id) -->
<select id="getUserList" resultMap="userList">
SELECT u.*,r.roleName FROM `smbms_user` u,`smbms_role` r
WHERE u.`userRole`=r.`id`
<if test="uRole!=null">
AND userRole=#{uRole}
</if>
<if test="uName!=null and uName!=''">
AND userName LIKE CONCAT('%',#{uName},'%')
</if>
</select>
说明:仅仅使用一个 if 元素,当查询条件 where 后面没有固定条件,无法处理多余的 and ,or 等关键字。且当不输入查询条件时,多余的 where 关键字也无法处理。为了智能处理 and、or、where 等关键字,if 元素应配合 where 元素一起使用。
使用 if+where 实现多条件查询
where 元素
    where 元素主要用来简化 SQL 语句中的 where 条件判断,并能智能地处理 and 和 or,不必担心多余关键字导致的语法错误。
    where 元素标签会自动识别其标签内是否有返回值,若有返回值,就插入一个 where 。此外,若该标签返回的内容是以 and或者or 开头的,会自动剔除。
//案例:根据用户名称(模糊查询)和用户 id 查询用户列表,且用户列表不需要显示角色名称,显示角色 id 即可,即不用进行连表查询。
    /**
     * 根据用户名称(模糊查询)和用户角色查询用户列表
     * @param userName 用户名称
     * @param userRole 用户角色
     * @return
     */
    public List<User> getUserList(@Param("uName")String userName,@Param("uRole")Integer userRole); 
<!-- 根据用户名称(模糊查询)和用户角色查询用户列表-->
    <select id="getUserList" resultType="user">
        SELECT * FROM `smbms_user`
        <where>
            <if test="uRole!=null">
                AND userRole=#{uRole}
            </if>
            <if test="uName!=null and uName!=''">
                AND userName LIKE CONCAT('%',#{uName},'%')
            </if>
        </where>
    </select>
    @Test  //测试根据用户名称(模糊查询)和用户角色查询用户列表
    public void testGetUserList() {
        SqlSession session=null;
        List<User> userList = new ArrayList<User>();
        try {
            session=MyBatisUtil.getSqlSession();
            String userName = null;
            Integer userRole =null;
            userList = session.getMapper(UserMapper.class).getUserList(userName, userRole);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            MyBatisUtil.close(session);
        }
        System.out.println("userlist.size ----> " + userList.size());
        for (User user : userList) {
            System.out.println(user);
        }
    }
说明:查询条件不是很多(一般不超过四个)且较为固定的情况下,最好采用多参数直接入参的方式(即 @Param 实现多参数入参),这样代码比较清晰,可读性强。
使用 if+trim 实现多条件查询
trim 元素
在 MyBatis 中处了使用 if+where 实现多条件查询,还有一个更为灵活的元素 trim 可以替代之前的做法。
trim 元素也会自动识别其标签内是否有返回值,若有返回值,会在自己包含的内容前加上某些前缀,也可在其后加上某些后缀,与之对应的属性是 prefix 和 suffix;也可把包含内容的首部某些内容覆盖(即忽略),或者把尾部的某些内容覆盖,与之对应的属性是 prefixOverrides 和 suffixOverrides;正因为 trim 有这样强大的功能,我们可以利用 trim 来替代 where 元素,并实现与 where 元素相同的效果。
trim 的属性
prefⅸ:前缀,作用是通过自动识别是否有返回值后, 在 trim 包含的内容上加上前缀。
suffix:后缀,作用是在 trim 包含的内容上加上后缀。
prefixOverrides:对于 trim 包含内容的首部(前缀)进行指定内容的忽略/删除。
suffixOverrides:对于 trim 包含内容的尾部(后缀)进行指定内容的忽略/删除。
//修改上面示例中 UserMapper.xml 中的代码,使用 if+trim 达到相同的效果。
    <!-- 根据用户名称(模糊查询)和用户角色查询用户列表 -->
    <select id="getUserList" resultType="user">
        SELECT * FROM `smbms_user`
        <trim prefix="where" prefixOverrides="and | or">
            <if test="uRole!=null">
                AND userRole=#{uRole}
            </if>
            <if test="uName!=null and uName!=''">
                AND userName LIKE CONCAT('%',#{uName},'%')
            </if>
        </trim>
    </select>
使用动态 SQL 实现更新操作
修改用户信息操作,在实际项目中,用户在进行信息的更新操作时,并不一定所有的数据都会进行修改,对于用户没有修改的数据,数据库不需要进行相应的更新操作。即更新用户表数据时,若某个参数传入值为 null 时,不需要 set 该字段。若要实现此需求,使用动态 SQL 中的 set 元素来处理。
set 元素
set 元素主要用于更新操作,它的主要功能和 where 元素差不多,主要是在包含的语句前输出一个 set ,若包含的语句是以逗号结束的,会自动把该逗号忽略掉,再配合 if 元素就可以动态地更新需要修改的字段;而不需修改的字段,则可以不再被更新。
使用 set 标签不仅可以动态地配置 set 关键字,还可剔除追加到条件末尾的任何不相关的逗号。
//案例:实现根据用户 id 修改用户信息的操作,要求不需要修改的字段,则可以不进行更新。 /**
* 修改操作:实现根据用户 id 修改用户信息的操作
* @param user 对象入参
* @return
*/
public int update(User user); <!--修改操作:实现根据用户 id 修改用户信息的操作 -->
<update id="update" parameterType="user">
UPDATE `smbms_user`
<set>
<if test="userCode != null">userCode=#{userCode},</if>
<if test="userName != null">userName=#{userName},</if>
<if test="userPassword != null">userPassword=#{userPassword},</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>
</set>
where id = #{id}
</update> @Test // 测试修改操作:实现根据用户 id 修改用户信息的操作
public void testUpdate() {
SqlSession session=null;
int count = 0;// 返回执行 SQL 影响的行数
try {
session=MyBatisUtil.getSqlSession();
User user = new User();
user.setId(16);
user.setUserName("测试用户修改");
user.setAddress("地址测试修改");
user.setModifyBy(1);
user.setModifyDate(new Date());
count = session.getMapper(UserMapper.class).update(user);
session.commit(); // 提交事务(MyBatisUtil 中设置了不自动提交事务,因此手动提交)
} catch (Exception e) {
e.printStackTrace();
session.rollback();// 发生异常就回滚
count = 0;
}finally{
MyBatisUtil.close(session);
}
System.out.println("执行 update 影响行数:" + count);
}
使用 if+trim 改造修改操作
使用 trim 元素来替代 set 元素,并实现与 set 一样的效果。
<!--修改操作:实现根据用户 id 修改用户信息的操作 -->
<update id="update" 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">userPassword=#{userPassword},</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>
动态 SQL(1)的更多相关文章
- 值得注意的ibatis动态sql语法格式
		
一.Ibatis常用动态sql语法,简单粗暴用一例子 <select id="iBatisSelectList" parameterClass="java.util ...
 - Mysql - 游标/动态sql/事务
		
游标这个在我目前的项目里面用的还不多, 但是其功能还是很强大的. 动态sql以前都没用过, 是跟着富士康(不是张全蛋的富土康哦)过来的同事学的. 还是挺好用的. 我的数据库方面, 跟他学了不少. 在此 ...
 - MyBatis4:动态SQL
		
什么是动态SQL MyBatis的一个强大特性之一通常是它的动态SQL能力.如果你有使用JDBC或其他相似框架的经验,你就明白条件串联SQL字符串在一起是多么地痛苦,确保不能忘了空格或者在列表的最后的 ...
 - 分享公司DAO层动态SQL的一些封装
		
主题 公司在DAO层使用的框架是Spring Data JPA,这个框架很好用,基本不需要自己写SQL或者HQL就能完成大部分事情,但是偶尔有一些复杂的查询还是需要自己手写原生的Native SQL或 ...
 - MySQL存储过程动态SQL语句的生成
		
用Mysql存储过程来完成动态SQL语句,使用存储过程有很好的执行效率: 现在有要求如下:根据输入的年份.国家.节假日类型查询一个节假日,我们可以使用一般的SQL语句嵌入到Java代码中,但是执行效率 ...
 - 【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】
		
一.动态SQL 什么是动态SQL,就是在不同的条件下,sql语句不相同的意思,曾经在“酒店会员管理系统”中写过大量的多条件查询,那是在SSH的环境中,所以只能在代码中进行判断,以下是其中一个多条件查询 ...
 - 自定义函数执行动态sql语句
		
--函数中不能调用动态SQL,使用用存储过程吧.如果还要对函数做其他操作,换成存储过程不方便,可以考虑把其他操作一起封装在存储过程里面.如: create proc [dbo].[FUN_YSCL ...
 - mybatis入门基础(五)----动态SQL
		
一:动态SQL 1.1.定义 mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 1.2.案例需求 用户信息综合查询列表这个statement的定义使用动态s ...
 - mybatis 动态sql表达式相关应用
		
一.mybatis 表达式简介 对于mybatis3 ,提供了一种动态sql的方式.通过动态sql我们可以直接在mybatis 的xm映射文件中直接通过条件判断的方式进行查询添加的拼接.mybatis ...
 - (转)Mybatis高级映射、动态SQL及获得自增主键
		
原文:http://www.cnblogs.com/edwinchen/p/4105278.html?utm_source=tuicool&utm_medium=referral 一.动态SQ ...
 
随机推荐
- Android SDK更新以及ADT更新出现问题的解决办法(转载)
			
转自:http://zyueqi.iteye.com/blog/1474323 问题描述 使用SDK Manager更新时出现问题Failed to fetch URL https://dl-ssl. ...
 - Java 反射机制详解(上)
			
一.什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java ...
 - java数组实现红包的方法
			
package Hongbao; import java.text.DecimalFormat; import java.util.Scanner; public class Hongbao { pu ...
 - RMAN-06564错误的原因及解决办法
			
今日在进行数据库恢复时,遭遇RMAN-06564错误,如下: RMAN> restore spfile from autobackup; Starting restore at 01-NOV-1 ...
 - jsp声明周期
			
https://www.w3cschool.cn/jsp/jsp-life-cycle.html 几点注意: jsp初始化期: 容器载入jsp文件后,它会在为请求提供任何服务前调用jspinit()方 ...
 - 189 Rotate Array 旋转数组
			
将包含 n 个元素的数组向右旋转 k 步.例如,如果 n = 7 , k = 3,给定数组 [1,2,3,4,5,6,7] ,向右旋转后的结果为 [5,6,7,1,2,3,4].注意:尽可能找 ...
 - D. Arpa's weak amphitheater and Mehrdad's valuable Hoses 分组背包模板题
			
http://codeforces.com/problemset/problem/742/D 并查集预处理出所有关系. 一开始的时候,我预处理所有关系后,然后选择全部的时候,另起了一个for,然后再判 ...
 - Abp Framework中文文档上线
			
感谢 ABP框架中国小组 给我们带来的ABP中文翻译,Web+为方便广大学习爱好者随时查阅,现推出了Gitbook风格的在线阅读文档:http://www.webplus.org.cn/documen ...
 - bootstrap框架栅格系统使用
			
使用的前端框架 bootstrap框架 Bootstrap是一个响应式的框架 我们在使用的时候主要使用的是它的网格系统, 1.bootstrap布局 布局容器:.container(用于固定宽度并支 ...
 - ES3之bind方法的实现模拟
			
扩展Function原型方法,此处用myBind来模拟bind实现 Function.prototype.myBind = function(o /*,args*/){ //闭包无法获取t ...