zoukankan      html  css  js  c++  java
  • Mybatis动态SQL


    动态SQL


    什么是动态SQL?

    MyBatis的官方文档中是这样介绍的?

    动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

    使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

    如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

    换句话说,我们可以根据传入参数的不同,来执行不同的查询条件。

    IF标签:

    如何使用?

    我们首先创建一个Mapper接口,起名为:UserMapper ,并增加一个方法

    public interface UserMapper {
        public List<User> findByCondition(User user);
    }
    

    同时创建一个xml文件,起名为UserMapper.xml 然后编写SQL

    <mapper namespace="com.dxh.dao.UserMapper">
        <select id="findByCondition" parameterType="com.dxh.pojo.User" resultType="com.dxh.pojo.User">
            SELECT * FROM user where 1=1
            <if test="id != null">
                  and id = #{id}
             </if>
             <if test="username != null">
                  and username = #{username}
             </if>
        </select>
    </mapper>
    

    这个SQL的意思是:

    • 当id不为null的时候执行的SQL是:SELECT * FROM user where id = #{id}
    • 当id为null的时候执行的SQL是 SELECT * FROM user where 1=1

    很明显我们可以看到where 1=1 是多余的,因此我们可以这样写:

        <select id="findByCondition" parameterType="com.dxh.pojo.User" resultType="com.dxh.pojo.User">
            SELECT * FROM user 
            <where>
                <if test="id != null">
                    and id = #{id}
                </if>
                <if test="username != null">
                  	and username = #{username}
                </if>
            </where>
        </select>
    

    测试:

    编写一个测试类:

    package com.dxh.test;
    
    import com.dxh.dao.UserMapper;
    import com.dxh.pojo.User;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    
    public class TestMain {
        @Test
        public void test1() throws IOException {
            InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
            SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
            SqlSession sqlSession = build.openSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = new User();
            user.setId(1);
            List<User> byCondition = mapper.findByCondition(user);
            for (User user1 : byCondition) {
                System.out.println(user1);
            }
            System.out.println("======");
            User user2 = new User();
            List<User> byCondition2 = mapper.findByCondition(user2);
            for (User user3 : byCondition2) {
                System.out.println(user3);
            }
    
        }
    }
    
    

    我们执行两次mapper.findByCondition(),分别传入user和user2,一个的id有被赋值,一个没有,最后的结果为:

    User{id=1, username='lucy'}
    ======
    User{id=1, username='lucy'}
    User{id=2, username='李四'}
    User{id=3, username='zhaowu'}
    

    foreach标签:

    当我们需要查询出 id为1、2、3时应该怎么做? SQL应该这样写:SELECT * FROM user where id in (1,2,3)。那么使用mybatis的foreach标签应该如何使用?

    如何使用?

    UserMapper接口中增加一个方法: List<User> findByIds(int[] arr);

      public List<User> findByIds(int[] arr);
    

    UserMapper.xml 中编写:

        <select id="findByIds" parameterType="list" resultType="com.dxh.pojo.User">
            SELECT * FROM user
            <where>
                <foreach collection="array" open="id in (" close=")" item="id" separator=",">
                    #{id}
                </foreach>
            </where>
        </select>
    

    我们可以看到,foreach中我们使用到了5个值:

    • collection 这里就是写我们传入的类型,如果是数组就是array ,如果是集合就是list
    • open 我们之前说到SELECT * FROM user where id in (1,2,3)正确的SQL应该这样写,那么open就是填写我们需要拼接的前半部分
    • close 填写我们需要拼接的后半部分
    • item 我们需要遍历的值是id,所以就填写id
    • separator ......where id in (1,2,3) 1,2,3之间用,分割。

    测试:

        @Test
        public void test2() throws IOException {
            InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
            SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
            SqlSession sqlSession = build.openSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int[] arr={1,3};
            List<User> byCondition = mapper.findByIds(arr);
            for (User user1 : byCondition) {
                System.out.println(user1);
            }
        }
    

    输出结果:

    User{id=1, username='lucy'}
    User{id=3, username='zhaowu'}
    

    正确~


    最后

    这里只是介绍了两个经常使用的标签,mybatis中还有很多标签,比如choose、when、otherwise、trim、set等等

    值得一说的是Mybatis的官方网站中已经支持中文了,母语看着更舒服~

    https://mybatis.org/mybatis-3/zh/

  • 相关阅读:
    VisualStudio2010配置OpenCV的一种一劳永逸的方法
    QT5 Failed to load platform plugin &quot;windows&quot; 终极解决方式 命令行问题
    轻松学习JavaScript二十二:DOM编程学习之节点操作
    Eclipse中安装TestNG插件
    Java Timer 定时器的使用
    技术开发团队的项目管理工具
    python里一个class可以定义多个构造函数
    python中的多继承
    python基础之使用os.system来执行系统命令
    python下划线变量的含义
  • 原文地址:https://www.cnblogs.com/isdxh/p/13956223.html
Copyright © 2011-2022 走看看