2021-05-03 11:00  阅读(175)
文章分类:MyBatis 教程 文章标签:MyBatisMyBatis 教程
©  原文作者:一点教程 原文地址:http://www.yiidian.com/springmvc/

动态SQL是MyBatis的一大强大功能,能帮助我们解决SQL拼接的困难,动态SQL元素和JSTL或基于类似XML 的文本处理器相似。

MyBatis的动态SQL分为以下:

  1. if
  2. choose
  3. where
  4. set
  5. sql
  6. foreach

1 if

1.1 作用

if就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。

1.2 Dao方法

    
    /**
       * if标签的使用
       * 一点教程网- www.yiidian.com
       */
    public List<Customer> queryByNameAndTelephone(Customer customer);

1.2 Dao映射配置

    
    <!--if标签的使用-->
    <select id="queryByNameAndTelephone" parameterType="com.yiidian.domain.Customer" resultType="com.yiidian.domain.Customer">
        SELECT * FROM t_customer
        WHERE 1=1
        <if test="name!=null and name!='' ">
            AND NAME LIKE #{name}
        </if>
        <if test="telephone!=null and telephone!='' ">
            AND telephone LIKE #{telephone}
        </if>
    </select>

可以看到,上面使用if标签来作了条件判断,这样可以根据用户填入的参数来动态加入查询条件。

1.3 测试类

    
    /**
     * if标签的使用
     * 一点教程网 - www.yiidian.com
     */
    @Test
    public void testQueryByNameAndTelephone(){
        //1.获取SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSession();
    
        //2.创建Dao代理对象
        CustomerDao customerDao = sqlSession.getMapper(CustomerDao.class);
    
        //3.调用方法
        Customer c = new Customer();
        c.setName("%小%");
    
        List<Customer> list = customerDao.queryByNameAndTelephone(c);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    
    
        //4.关闭连接
        sqlSession.close();
    }

1.4 测试结果

202105031100205221.png

从结果看到,telephone为null,所以最后的sql语句并没有拼接telephone条件。

2 choose

2.1 作用

choose元素的作用就相当于Java中的switch语句,基本上跟JSTL中的choose的作用和用法是一样的,通常都是与when和otherwise搭配的。

2.2 Dao方法

    
    /**
     * choose标签的使用
     */
    public List<Customer> queryByNameAndTelephone2(Customer customer);

2.3 Dao映射配置

    
    <!--choose标签的使用-->
    <select id="queryByNameAndTelephone2" parameterType="com.yiidian.domain.Customer" resultType="com.yiidian.domain.Customer">
        SELECT * FROM t_customer
        <where>
            <choose>
                <when test="name!=null and name!='' ">
                    AND NAME LIKE #{name}
                </when>
                <when test="telephone!=null and telephone!='' ">
                    AND telephone LIKE #{telephone}
                </when>
                <otherwise>
    
                </otherwise>
            </choose>
        </where>
    </select>

2.4 测试类

    
    /**
     * choose标签的使用
     * 一点教程网 - www.yiidian.com
     */
    @Test
    public void testQueryByNameAndTelephone2(){
        //1.获取SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSession();
    
        //2.创建Dao代理对象
        CustomerDao customerDao = sqlSession.getMapper(CustomerDao.class);
    
        //3.调用方法
        Customer c = new Customer();
        c.setName("%小%");
    
        List<Customer> list = customerDao.queryByNameAndTelephone2(c);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    
    
        //4.关闭连接
        sqlSession.close();
    }

2.5 测试结果

202105031100206922.png

如果name不为空,则拼接name的条件。如果telephone不为空,则拼接的telephone的条件。注意的是,otherwise的条件可以为空。

3 where

3.1 作用

where语句的作用主要是简化SQL语句中where中的条件判断的。MyBatis会智能的帮你处理这些情况:如果所有的条件都不满足那么MyBatis就会查出所有的记录,如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。

3.2 Dao方法

    
    /**
     * where标签的使用
     */
    public List<Customer> queryByNameAndTelephone3(Customer customer);

3.3 Dao映射配置

    
    <!--where标签的使用-->
    <select id="queryByNameAndTelephone3" parameterType="com.yiidian.domain.Customer" resultType="com.yiidian.domain.Customer">
        SELECT * FROM t_customer
        <where>
            <if test="name!=null and name!='' ">
                AND NAME LIKE #{name}
            </if>
            <if test="telephone!=null and telephone!='' ">
                AND telephone LIKE #{telephone}
            </if>
        </where>
    </select>

3.4 测试类

    
    /**
     * where标签的使用
     * 一点教程网 - www.yiidian.com
     */
    @Test
    public void testQueryByNameAndTelephone3(){
        //1.获取SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSession();
    
        //2.创建Dao代理对象
        CustomerDao customerDao = sqlSession.getMapper(CustomerDao.class);
    
        //3.调用方法
        Customer c = new Customer();
        c.setName("%小%");
    
        List<Customer> list = customerDao.queryByNameAndTelephone3(c);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    
    
        //4.关闭连接
        sqlSession.close();
    }

3.5 测试结果

202105031100208763.png

从结果看到,第一个name条件前面的and关键词被自动删除。

4 sql

4.1 作用

MyBatis中sql标签定义SQL片段,include标签引用,可以复用SQL片段。

4.2 Dao方法

    
    /**
     * sql标签的使用
     */
    public List<Customer> queryByNameAndTelephone4(Customer customer);

4.3 Dao映射配置

    
    <!--sql标签的使用-->
    <sql id="customerField">
        select id,name,gender,telephone from t_customer
    </sql>
    
    <select id="queryByNameAndTelephone4" parameterType="com.yiidian.domain.Customer" resultType="com.yiidian.domain.Customer">
        <include refid="customerField"/>
        <where>
            <if test="name!=null and name!='' ">
                AND NAME LIKE #{name}
            </if>
            <if test="telephone!=null and telephone!='' ">
                AND telephone LIKE #{telephone}
            </if>
        </where>
    </select>

从配置看到,我们把反复使用的select语句使用sql标签抽取出来,然后使用include标签引用,这样配置的复用性大大地提高啦。

4.4 测试类

    
    /**
     * sql标签的使用
     * 一点教程网 - www.yiidian.com
     */
    @Test
    public void testQueryByNameAndTelephone4(){
        //1.获取SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSession();
    
        //2.创建Dao代理对象
        CustomerDao customerDao = sqlSession.getMapper(CustomerDao.class);
    
        //3.调用方法
        Customer c = new Customer();
        c.setName("%小%");
    
        List<Customer> list = customerDao.queryByNameAndTelephone4(c);
        for (Customer customer : list) {
            System.out.println(customer);
        }
    
    
        //4.关闭连接
        sqlSession.close();
    }

4.5 测试结果

202105031100210374.png

5 foreach

5.1 作用

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有:

属性名 说明
item 集合中每一个元素进行迭代时的别名
index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置
collection 该属性是必须指定的,该值存在3种情况:1)如果传入的是单参数且参数类型是一个List的时候,collection属性值为list2)如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array3)如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
open 表示该语句以什么开始
separator 表示在每次进行迭代之间以什么符号作为分隔符
close 表示以什么结束

5.2 Dao方法

    
    /**
     * foreach标签的使用
     */
    public void deleteCustomerByIn(List<Integer> custIds);

5.3 Dao映射配置

    
    <!--foreach标签的使用-->
    <select id="deleteCustomerByIn" parameterType="integer">
        DELETE FROM t_customer WHERE
        <foreach collection="list" item="id" open="id IN(" close=")" separator=",">
            #{id}
        </foreach>
    </select>

这里传入的参数是List类型,所以collection属性为list。

5.4 测试类

    
    /**
     * foreach标签的使用
     * 一点教程网 - www.yiidian.com
     */
    @Test
    public void testDeleteCustomerByIn(){
        //1.获取SqlSession对象
        SqlSession sqlSession = MyBatisUtils.getSession();
    
        //2.创建Dao代理对象
        CustomerDao customerDao = sqlSession.getMapper(CustomerDao.class);
    
        //3.调用方法
        List<Integer> custIds = new ArrayList<>();
        custIds.add(6);
        custIds.add(7);
    
        customerDao.deleteCustomerByIn(custIds);
    
        //提交事务
        sqlSession.commit();
    
        //4.关闭连接
        sqlSession.close();
    }

5.5 测试结果

202105031100212155.png

源码下载:https://pan.baidu.com/s/1660egFIt8-0lvJrnAmCyvw

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> MyBatis 动态SQL
上一篇
MyBatis 输出参数
下一篇
MyBatis 一对一关系映射