• Mybatis的动态sql


    什么是动态sql:动态sql就是根据不同的条件生成不同的sql语句。

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

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

    搭建环境

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    创建一个基础工程

    1. 导包

    2. 编写配置文件

    3. 编写实体类

      import lombok.Data;
      
      import java.time.LocalDateTime;
      
      /**
       * @Description: 类描述
       * @Author: 周南
       * @Date: 2022/09/29 17:40
       */
      @Data
      public class Blog {
          private String id;
          private String title;
          private String author;
          private LocalDateTime createTime;
          private int views;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

    public interface BlogMapper {
    //插入数据

    int addBook(Blog blog);
    //查询blog
    List queryBlogIF(Map map);
    List queryBlogChoose(Map map);
    int updateBlog(Map map);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    }

    
    
    
    4. 编写实体类对应Mapper接口和Mapper.xml文件
    
    
    
    ## if
    
    ```xml
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    choose (when, otherwise)

        <select id="getBlogList" parameterType="map" resultType="com.zyy.pojo.Blog">
            select id,title,author,create_time createTime,views from blog
            <where>
                <choose>
                    <when test="title != null">
                        title like #{title}
                    </when>
                    <when test="author != null">
                        and author = #{author}
                    </when>
                    <otherwise>
                        and views=#{views}
                    </otherwise>
                </choose>
            </where>
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    trim (where, set)

    where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

        <select id="getBlogList" parameterType="map" resultType="com.zyy.pojo.Blog">
            select id,title,author,create_time createTime,views from blog
            <where>
                <if test="title != null">
                    title like #{title}
                if>
                <if test="author != null">
                    and author = #{author}
                if>
            where>
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
        <update id="updateBlog" parameterType="map">
            update blog
            <set>
                <if test="title != null">
                    title=#{title},
                if>
                <if test="author != null">
                    author=#{author}
                if>
            set>
            where id=#{id}
        update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:

    <trim prefix="WHERE" prefixOverrides="AND |OR ">
      ...
    trim>
    
    • 1
    • 2
    • 3
    <trim prefix="SET" suffixOverrides=",">
      ...
    trim>
    
    • 1
    • 2
    • 3

    所谓的动态sql。本质还是sql语句,只是我们可以在sql层面,去执行一个逻辑代码

    SQL片段

    有的时候,我们可能会将一些功能的部分抽取出来,方便复用

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

          <sql id="title-author-views">
              <choose>
                  <when test="title != null">
                      title like #{title}
                  when>
                  <when test="author != null">
                      and author = #{author}
                  when>
                  <otherwise>
                      and views=#{views}
                  otherwise>
              choose>
          sql>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    2. 在需要使用的地方使用include标签引用即可

          <select id="getBlogList" parameterType="map" resultType="com.zyy.pojo.Blog">
              select id,title,author,create_time createTime,views from blog
              <where>
                <include refid="title-author-views"/>
              where>
          select>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    注意事项:

    • 最好基于单表来定义sql片段
    • 不要存在where标签

    foreach

        
        <select id="getBlogListForeach" parameterType="map" resultType="com.zyy.pojo.Blog">
          select id,title,author,create_time createTime,views from blog
          <where>
              <foreach collection="idList" item="id" open="(" close=")" separator="or">
                  id = #{id}
              foreach>
          where>
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    动态sql就是在拼接sql语句,我们只要保证sql正确性,按照sql的格式,去排列组合就可以了

  • 相关阅读:
    Spring之ioc
    boss:整个卡尔曼滤波器的简单案例——估计机器人位置
    C++&QT day1
    Transformer论文精读
    ElasticSearch底层读写工作原理
    K8S知识点(七)
    spring security调用过程;及自定义改造
    java后端:nacos 实现动态配置
    学习Oracle数据库的新建表的基本操作(二)
    C++数据结构稀疏矩阵运算(含加减乘及快速转置)
  • 原文地址:https://blog.csdn.net/ZN175623/article/details/127594394