动态SQL(IF、choose、when、otherwise、trim、where、set、SQL片段、Foreach)

12、动态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. 编写实体类对应Mapper接口和Mapper.xml文件

 

IF
  <select id="queryBlogIF" resultType="com.kuang.pojo.Blog" parameterType="map">
      select * from mybatis.blog where 1=1
       <if test="author != null">
          and author=#{author}
       </if>
       <if test="views != null">
          and views=#{views}
       </if>
   </select>
    public void queryBlogIF(){
       SqlSession sqlSession = MybatisUtils.getSqlSession();
       BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
       HashMap map = new HashMap();
       map.put("author","荣哥");
       map.put("views","9999");
       List<Blog> blogs = mapper.queryBlogIF(map);
       for (Blog blog : blogs) {
           System.out.println(blog);
      }
       sqlSession.close();
  }

就能查出满足author=荣哥,views=9999的记录

 

choose、when、otherwise
    <select id="queryBlogChoose" parameterType="map" resultType="com.kuang.pojo.Blog">
      select * from mybatis.blog
       <where>
           <choose>
               <when test="title != null">
                  title = #{title}
               </when>
               <when test="author != null">
                  and author = #{author}
               </when>
               <otherwise>
                  and views = #{views}
               </otherwise>
           </choose>
       </where>
   </select>
trim、where、set
        select * from mybatis.blog
    //where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句,
    //若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
    //如果没有where标签第一个and要去掉,不然报错。
       <where>
       <if test="title!=null">
          and title = #{title}
       </if>
       <if test="author != null">
          and author like #{author}
       </if>
       <if test="views != null">
          and views=#{views}
       </if>
       </where>
   //set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
  <update id="updateBlog" parameterType="map">
      update mybatis.blog
       <set>
           <if test="title != null">
              title = #{title},
           </if>
           <if test="author != null">
              author = #{author}
           </if>
       </set>
      where id = #{id}
   </update>

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

 

SQL片段

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

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

        <sql id="id-title-author">
           <if test="title!=null">
              and title = #{title}
           </if>
           <if test="author != null">
              and author like #{author}
           </if>
       </sql>
  2. 在需要使用的地方使用include标签引用即可

        <select id="queryBlogIF" resultType="com.kuang.pojo.Blog" parameterType="map">
          select * from mybatis.blog
           <where>
           <include refid="id-title-author"></include>
           </where>
       </select>

注意事项:

  • 最好基于单表来定义SQL片段

  • 不要存在where标签

 

Foreach
select * from user where 1=1 and(id=1 or id=2 or id=3)

 <foreach item="id" collection="ids"
     open="(" separator="or" close=")">
       #{id}
 </foreach>
 (id=1 or id=2 or id=3)
 

 

 

<!--select * from mybatis.blog where 1=1 and(id=1 or id=2 or id=3)

   我们现在传递一个万能的map,这map中可以存在一个集合!
-->
   <select id="queryBlogForeach" parameterType="map" resultType="com.kuang.pojo.Blog">
      select * from mybatis.blog

       <where>
           <foreach collection="ids" item="id" open="and (" separator="or" close=")">
              id=#{id}
           </foreach>
       </where>
   </select>

 

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

建议:

  • 先在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可!

posted @ 2021-10-25 10:05  敲代码的体育生  阅读(347)  评论(0)    收藏  举报