zoukankan      html  css  js  c++  java
  • 12、动态SQL

    什么是动态SQL?

      

      动态 SQL 是 MyBatis 的强大特性之一。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

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

    • if
    • choose (when, otherwise)
    • trim (where, set)
    • foreach

    基础工程:

    1、创建sql

    CREATE TABLE `blog`(
    `id` VARCHAR(50) NOT NULL COMMENT '博客id',
    `title` VARCHAR(100) NOT NULL COMMENT '博客标题',
    `author` VARCHAR(30) NOT NULL COMMENT '博客作者',
    `create_time` DATETIME NOT NULL COMMENT '创建时间',
    `views` INT(30) NOT NULL COMMENT '浏览量'
    )ENGINE=INNODB DEFAULT CHARSET=utf8

    2、导包

    3、创建pojo实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Blog {
        private int id;
        private String title;
        private String author;
        private Date create_time;
        private int views;
    }

    4、编写实体类对应mapper接口 和 mapper.xml文件

    =========================测试====================================

    Where、if

      提供了可选的查找文本功能。

      where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。

      而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

    <select id="selBlogIf" resultType="blog" parameterType="map">
    /*1=1是为了让if为false的情况下能把所有的记录查出来*/
    select * from blog
    <where>
    <if test="title != null">
    and title = #{title}
    </if>
    <if test="author != null">
    and author = #{author}
    </if>
    </where>
    </select>  
        @Test
        public void selBlogIfTest(){
            SqlSession sqlSession = MybatisUtil.getSqlSession();
            BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    
            Map map = new HashMap();
            map.put("title","Java");
            List<Blog> blogs = mapper.selBlogIf(map);
            for (Blog blog : blogs) {
                System.out.println(blog);
            }
            sqlSession.close();
        }

    添加了title的值,说明上面发判断为true,就能查出来:title = "java"的记录

    choose、when、otherwise

      有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

    • 匹配顺序是从第一个进行选择,第一个成立就执行第一个中的匹配,
    • 如果第一个第二个数据都匹配的话,还是按第一个中的执行
    • 所有条件不匹配就会执行otherwise
        <select id="selBlogIf" resultType="blog" parameterType="map">
            select * from blog
            <where>
                <choose>
                    <when test="author != null">
                        and author = #{author}
                    </when>
                    <when test="title != null">
                        and title = #{title}
                    </when>
                    <otherwise>
                        and views = #{views}
                    </otherwise>
                </choose>
            </where>
        </select>

    where、set

    • set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
    <update id="updateBlog" parameterType="map">
            update blog
            <set>
                <if test="author != null">
                    author = #{author}
                </if>
            </set>
    
            <where>
                <if test="id != null">
                    id = #{id}
                </if>
            </where>
        </update>
        @Test
        public void updateBlogIfTest(){
            SqlSession sqlSession = MybatisUtil.getSqlSession();
            BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    
            Map map = new HashMap();
    
            map.put("id","4bdfaea75d5c416fb2c10a6d4c51cf8f");
            map.put("author","zhangzhixi");
    
            mapper.updateBlog(map);
            sqlSession.commit();
            sqlSession.close();
        }

    修改成功!

    SQL片段:

      将需要的代码抽取出来,实现代码复用

      1、使用sql标签抽取公共部分

      2、使用include标签进行引入即可

        <sql id="title_author">
            <if test="title != null">
                and title = #{title}
            </if>
            <if test="author != null">
                and title = #{author}
            </if>
        </sql>
        <select id="conditionQuery" resultType="blog" parameterType="map">
            select * from blog
            <where>
                <include refid="title_author"></include>
            </where>
        </select>
        @Test
        public void conditionQueryTest(){
            SqlSession sqlSession = MybatisUtil.getSqlSession();
            BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    
            Map map = new HashMap();
            map.put("title","Java");
    
            List<Blog> blogs = mapper.conditionQuery(map);
            for (Blog blog : blogs) {
                System.out.println(blog);
            }
            sqlSession.close();
        }

    通过测试!查询到的结果跟if嵌套在where中的结果是一样的

    注意事项

     1、最好基于单表来定义sql片段

     2、sql片段中不要存在where标签

  • 相关阅读:
    装饰着模式
    观察者模式
    策略模式
    nginx配置图片防盗链
    nginx配置文件详解( 看着好长,其实不长,看了就知道了,精心整理,有些配置也是没用到呢 )
    php引用计数的基本知识
    PHP运行模式
    CURL常用命令--update20151015
    memcache相同主域名下的session共享
    memcached命令行操作详解,命令选项的详细解释
  • 原文地址:https://www.cnblogs.com/zhangzhixi/p/14213354.html
Copyright © 2011-2022 走看看