首页 > 数据库 >MyBatis的使用八(动态SQL)

MyBatis的使用八(动态SQL)

时间:2023-02-05 15:01:07浏览次数:43  
标签:02 05 age DEBUG emp SQL MyBatis DynamicMapper 动态

本主要讲述mybatis处理动态sql语句

一. 问题引入

  前端展示的数据表格中,查询条件可能不止一个,如何将用户输入的多个查询条件,拼接到sql语句中呢?

  DynamicMapper接口声明如下

public interface DynamicMapper {

    // 动态查询员工信息
    List<Employee> selectEmpDynamic(@Param("emp") Employee emp);
}

  如何在DynamicMapper.xml文件中,编写sql语句,使其动态查询呢?

二. 动态SQL查询

  1. <if>标签

  DynamicMapper.xml文件声明如下

    <!--// 动态查询员工信息
    List<Employee> selectEmpDynamic(Employee emp);-->
    <select id="selectEmpDynamic" resultType="Employee">
        select * from t_emp where 1=1
        <if test="emp.empName != null and emp.empName != '' ">
            and emp_name = #{emp.empName}
        </if>
        <if test="emp.age != null and emp.age != '' ">
            and age = #{emp.age}
        </if>
        <if test="emp.gender != null and emp.gender != '' ">
            and gender = #{emp.gender}
        </if>
    </select>

  测试test

    @Test
    // 测试动态查询
    public void test01(){
        SqlSession sqlSession = SQLSessionUtils.getSqlSession();
        DynamicMapper mapper = sqlSession.getMapper(DynamicMapper.class);
        Employee emp = new Employee(null, "", 23, "");
        List<Employee> list = mapper.selectEmpDynamic(emp);
        System.out.println(list);
    }

  运行结果如下

DEBUG 02-05 13:49:28,390 ==>  Preparing: select * from t_emp where 1=1 and age = ? (BaseJdbcLogger.java:137) 
DEBUG 02-05 13:49:28,432 ==> Parameters: 23(Integer) (BaseJdbcLogger.java:137) 
DEBUG 02-05 13:49:28,461 <==      Total: 1 (BaseJdbcLogger.java:137) 
[Employee{empId=1, empName='张三', age=23, gender='男', dept=null}]

  注意:单独使用 < if > 标签时,需要在where后面添加恒成立的条件,例如 1=1,之后在< if >标签中的test写判断条件

  2. <where> + <if>标签

  DynamicMapper.xml文件声明如下

    <select id="selectEmpDynamicTwo" resultType="Employee">
        select * from t_emp
        <where>
            <if test="emp.empName != null and emp.empName != '' ">
                and emp_name = #{emp.empName}
            </if>
            <if test="emp.age != null and emp.age != '' ">
                and age = #{emp.age} and
            </if>
            <if test="emp.gender != null and emp.gender != '' ">
                and gender = #{emp.gender}
            </if>
        </where>
    </select>

  测试test1

    @Test
    // 测试动态查询
    public void test01(){
        SqlSession sqlSession = SQLSessionUtils.getSqlSession();
        DynamicMapper mapper = sqlSession.getMapper(DynamicMapper.class);
        Employee emp = new Employee(null, "张三", 23, "");
        List<Employee> list = mapper.selectEmpDynamic(emp);
        System.out.println(list);
    }

  test1 运行结果如下

DEBUG 02-05 14:00:47,159 ==>  Preparing: select * from t_emp WHERE emp_name = ? and age = ? (BaseJdbcLogger.java:137) 
DEBUG 02-05 14:00:47,190 ==> Parameters: 张三(String), 23(Integer) (BaseJdbcLogger.java:137) 
DEBUG 02-05 14:00:47,211 <==      Total: 1 (BaseJdbcLogger.java:137) 
[Employee{empId=1, empName='张三', age=23, gender='男', dept=null}]

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

  但是当DynamicMapper.xml声明如下

    <select id="selectEmpDynamic" resultType="Employee">
        select * from t_emp
        <where>
            <if test="emp.empName != null and emp.empName != '' ">
                emp_name = #{emp.empName} and
            </if>
            <if test="emp.age != null and emp.age != '' ">
                age = #{emp.age} and
            </if>
            <if test="emp.gender != null and emp.gender != '' ">
                gender = #{emp.gender}
            </if>
        </where>
    </select>

  测试test2

    @Test
    // 测试动态查询
    public void test01(){
        SqlSession sqlSession = SQLSessionUtils.getSqlSession();
        DynamicMapper mapper = sqlSession.getMapper(DynamicMapper.class);
        Employee emp = new Employee(null, "张三", 23, "");
        List<Employee> list = mapper.selectEmpDynamic(emp);
        System.out.println(list);
    }

  test2 运行结果如下

DEBUG 02-05 14:08:29,175 ==>  Preparing: select * from t_emp WHERE emp_name = ? and age = ? and (BaseJdbcLogger.java:137) 
DEBUG 02-05 14:08:29,206 ==> Parameters: 张三(String), 23(Integer) (BaseJdbcLogger.java:137) 

  sql语句出现错误,即<where>标签无法去除SQL子句后面的and或者or。

  3. <trim> + <if> 标签

  DynamicMapper.xml文件声明如下

     <select id="selectEmpDynamic" resultType="Employee">
        select * from t_emp
        <!--prefix="where" 前缀添加where
        suffix="where" 后缀添加where
        prefixOverrides="and" 前缀删除and
        suffixOverrides="and" 后缀删除and-->
        <trim prefix="where" suffixOverrides="and">
            <if test="emp.empName != null and emp.empName != '' ">
                emp_name = #{emp.empName} and
            </if>
            <if test="emp.age != null and emp.age != '' ">
                age = #{emp.age} and
            </if>
            <if test="emp.gender != null and emp.gender != '' ">
                gender = #{emp.gender}
            </if>
        </trim>
    </select>

  注意:<trim>标签的功能比<where>标签的功能更加丰富

  test2运行结果如下

DEBUG 02-05 14:14:51,893 ==>  Preparing: select * from t_emp where emp_name = ? and age = ? (BaseJdbcLogger.java:137) 
DEBUG 02-05 14:14:51,924 ==> Parameters: 张三(String), 23(Integer) (BaseJdbcLogger.java:137) 
DEBUG 02-05 14:14:51,943 <==      Total: 1 (BaseJdbcLogger.java:137) 
[Employee{empId=1, empName='张三', age=23, gender='男', dept=null}]

  完美解决and在SQL子句后面的问题。

三. 批量增加【删除】

  1. 批量增加

  DynamicMapper接口声明如下

public interface DynamicMapper {

    // 批量添加emp对象
    int insertEmpList(@Param("emps") List<Employee> emps);
}

  DynamicMapper.xml文件声明如下

    <!--// 批量添加emp对象
    int insertEmpList(@Param("emps") List<Employee> emps);-->
    <insert id="insertEmpList" >
        insert into t_emp values
        <foreach collection="emps" item="emp" separator=",">
            (null,#{emp.empName},#{emp.age},#{emp.gender},null)
        </foreach>
    </insert>

  2. 批量删除

  DynamicMapper接口声明如下

public interface DynamicMapper {

    // 批量删除emp对象
    int deleteEmpList(@Param("empIds") Integer[] empIds);
}

  DynamicMapper.xml文件声明如下

    <!--// 批量删除emp对象-->
    <!--int deleteEmpList(@Param("empIds") Integer[] empIds);-->
    <!--方式1: -->
    <delete id="deleteEmpListOne" >
        delete from t_emp
        where emp_id in
        (
            <foreach collection="empIds" item="empId" separator=",">
                #{empId}
            </foreach>
            )
    </delete>

    <!--方式2: -->
    <delete id="deleteEmpListTwo" >
        delete from t_emp
        where emp_id in
        <foreach collection="empIds" item="empId" separator="," open="(" close=")">
            #{empId}
        </foreach>
    </delete>

    <!--方式3: -->
    <delete id="deleteEmpList" >
        delete from t_emp
        where
        <foreach collection="empIds" item="empId" separator="or">
            emp_id = #{empId}
        </foreach>
    </delete>

  注意:< foreach >标签的使用,

    collecion:传入的集合【数组】名;

    item:集合【数组】中元素的类型;

    separator:以指定字符串为分隔符;

    open:以指定字符串开始,close:以指定字符串结尾。

    

 

标签:02,05,age,DEBUG,emp,SQL,MyBatis,DynamicMapper,动态
From: https://www.cnblogs.com/zwgitOne123/p/17093361.html

相关文章

  • Spring整合Mybatis
    首先导入依赖1<properties>2<!--版本锁定-->3<spring.version>5.0.2.RELEASE</spring.version>4<log4j.version>1.2.17</log4j.version>......
  • [MySQL] 《数据库系统概念》阅读笔记
    第二章关系数据库在关系模型(relationalmodel)中,关系用来指代表(table),元组用来指代行(row),表中的一行代表了一组值之间的一种联系,行中的每一列(column)代表一个属性,属性允许的......
  • mac-docker安装使用mysql
    参考:https://blog.csdn.net/m0_67402588/article/details/1260751861、下载镜像,注意这里要下载适配了arm架构的镜像源dockerpullmysql/mysql-server2、创建容器dock......
  • 美团索命一问:一个SQL ,怎么分析加了哪些锁? 含4大场景、8个规则
    背景说明:美团问数据库应该是非常多的,尤其喜欢考手写SQL然后问你这个SQL语句上面加了哪些锁,你会发现其他厂面试基本很少会这样考,所以很多小伙伴遇到这种问题的时候都......
  • SQLSERVER 快照隔离级别 到底怎么理解?
    一:背景1.讲故事上一篇写完SQLSERVER的四个事务隔离级别到底怎么理解?之后,有朋友留言问什么时候可以把snapshot隔离级别给补上,这篇就来安排,快照隔离级别看起来很魔法......
  • 2023年SQL大厂高频实战面试题(详细解析)
    大家好,我是宁一。已经连续四个周没有休息了,最近主业、副业都是忙碌的巅峰期,晚上11点下班回家,再写课写到凌晨两点。连续一个多月连轴转,每天最大的愿望,就是睡足觉。这一阶段终......
  • sql计算众数及中位数
    众数众数:情况①:一组数据中,出现次数最多的数就叫这组数据的众数。举例:1,2,3,3,4的众数是3。情况②:如果有两个或两个以上个数出现次数都是最多的,那么这几个数都是这组数......
  • MyBatis自动配置解析
    今天,我们来分析一下MyBatis的自动配置解析mybatis的自动化配置类不在springboot中,下面搜索不到 需要在pom中添加mybatis的场景启动器<dependency>......
  • 动态规划
    动态规划算法设计的一种思想将问题分解为相互重叠的子问题,对子问题进行求解,从而解决原问题1.动态规划和分治区别分治的子问题,相互独立,互不干扰动态规划的子问题......
  • 混合应用字符串插值、字符串格式方法生成动态查询语句
    Strings=String.Format("select*fromPrice_ItemDeptswhereFeeDeptID={0}{1}{2}",$"'{deptID}'",string.IsNullOrEmpty(categoryID)?""......