Mybatis之动态SQL

2021/12/5 19:46:47

本文主要是介绍Mybatis之动态SQL,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Mybatis

12、动态SQL

12.1、简介

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

  • 利用动态SQL这一特性可以彻底摆脱这种痛苦。

  • 动态SQL元素和JSTL或基于类似XML的文本处理器相似。

  • 在MyBatis之前的版本中,有很多元素需要花时间了解。

  • MyBatis3大大精简了元素种类,现在只需学习原来一半的元素便可。

  • MyBatis 采用功能强大的基于OGNL的表达式来淘汰其它大部分元素。

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

  • 建议:

    • 先在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL实现通用即可。
  • if 
    choose(when,otherwise)
    trim(where,set)
    foreach
    

12.2、搭建环境

  • 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;
      
  • 创建一个基础工程

    • 导包。

    • 编写配置文件。

    • 编写实体类。

      • public class Blog {
            private String id;
            private String title;
            private String author;
            private Date createTime;//属性名和字段名不一致
            private int views;
        }
        
    • 编写实体类对应Mapper接口和Mapper.xml文件。

      • //插入数据
        int addBlog(Blog blog);
        
      • <insert id="addBlog" parameterType="blog">
            insert into blog (id, title, author, create_time, views) values
                (#{id},#{title},#{author},#{createTime},#{views})
        </insert>
        
    • IDUtils工具类

      • @SuppressWarnings("all")  //抑制警告
        public class IDUtils {
            public static String getId(){
                return UUID.randomUUID().toString().replaceAll("-","");
            }
            @Test
            public void test(){
                System.out.println(IDUtils.getId());
                System.out.println(IDUtils.getId());
                System.out.println(IDUtils.getId());
            }
        }
        
      • 抑制警告

        • @SuppressWarnings("all")
    • 测试

      • @Test
            public void testAddBlog() {
                SqlSession sqlSession = MybatisUtils.getSqlSession();
                BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
                Blog blog = new Blog();
                blog.setId(IDUtils.getId());
                blog.setTitle("Mybatis如此简单");
                blog.setAuthor("Jcooling");
                blog.setCreateTime(new Date());
                blog.setViews(9999);
                mapper.addBlog(blog);
        
                blog.setId(IDUtils.getId());
                blog.setTitle("Java如此简单");
                mapper.addBlog(blog);
        
                blog.setId(IDUtils.getId());
                blog.setTitle("Spring如此简单");
                mapper.addBlog(blog);
        
                blog.setId(IDUtils.getId());
                blog.setTitle("Linux如此简单");
                mapper.addBlog(blog);
                sqlSession.commit();
                sqlSession.close();
            }
        

12.3、IF

  • 接口类

    • //查询博客
      List<Blog> queryBlogIf(Map map);
      
  • 对应xml

    • <select id="queryBlogIf" parameterType="map" resultType="blog">
              select * from blog where 1=1
                 <if test="title!=null">
                     and title=#{title}
                 </if>
              <if test="author!=null">
                     and author=#{author}
                 </if>
          </select>
      
  • 测试

    • @Test
          public void testQueryBlogIf() {
              SqlSession sqlSession = MybatisUtils.getSqlSession();
              BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
              HashMap map = new HashMap();
             // map.put("title","Linux如此简单");
              map.put("author","JCooling");
              List<Blog> blogs = mapper.queryBlogIf(map);
              for (Blog blog : blogs) {
                  System.out.println(blog);
              }
              sqlSession.close();
          }
      

12.4、choose(when,otherwise)

  • 接口类

    • //查询
      List<Blog> queryBlogChoose(Map map);
      
  • 对应xml

    •  <select id="queryBlogChoose"  parameterType="map" resultType="blog">
             select * from 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>
      
  • 测试

    •  @Test
          public void testQueryBlogChoose() {
              SqlSession sqlSession = MybatisUtils.getSqlSession();
              BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
              HashMap map = new HashMap();
              map.put("title","Linux如此简单");
             // map.put("author","JCooling");
              map.put("views","9999");
              List<Blog> blogs = mapper.queryBlogChoose(map);
              for (Blog blog : blogs) {
                  System.out.println(blog);
              }
              sqlSession.close();
          }
      

12.5、trim(where,set)

  • 接口类

    • //查询博客
          List<Blog> queryBlogIf(Map map);
      //更新博客
          int updateBlogSet(Map map);
      
  • 对应xml

    •  <select id="queryBlogIf" parameterType="map" resultType="blog">
               select * from blog 
           <where>
                  <if test="title!=null">
                      title=#{title}
                  </if>
               <if test="author!=null">
                      and author=#{author}
                  </if>
               </where>
        </select>
       
       <update id="updateBlogSet" parameterType="map">
            update blog
       <set>
       <if test="title!=null">
          title=#{title},
      </if>
      <if test="author!=null">
           author=#{author}
      </if>
      </set>
            where id=#{id}
      </update>
      
  • 测试

    •  @Test
           public void testQueryBlogIf() {
             //同前
           }
       @Test
           public void testUpdateBlogSet() {
               SqlSession sqlSession = MybatisUtils.getSqlSession();
               BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
               HashMap map = new HashMap();
               map.put("title","Linux如此简单2");
               //map.put("author","JCooling");
               map.put("id","66c94df75eb34c8eab1a82c415b28dc2");
               int i = mapper.updateBlogSet(map);
               if (i==1) {
                  System.out.println("更新成功");
              }else {
                  System.out.println("更新失败");
              }
              sqlSession.commit();
              sqlSession.close();
          }
      
  • set元素会动态前置set关键字,同时也会删掉无关的逗号。

  • trim

    • //prefixOverrides  前缀
      //suffixOverrides   后缀
      <trim prefix="where" prefixOverrides="and|or" suffixOverrides=""></trim>
      
  • 所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码。

12.6、foreach

  • 动态SQL的另外一个常用的操作需求是对一个集合进行遍历,|通常是在构建IN条件语句的时候。

  • foreach元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。

  • 它也允许你指定开头与结尾的字符串以及迭代结果之间放置分隔符。不会偶然地附加多余的分隔符。

  • 注意

    • 你可以将任何可迭代对象(如List、Set等)、Map对象或者数组对象传递给foreach作为集合参数。
    • 当使用可迭代对象或者数组时,index是当前迭代的次数,item的值是本次迭代获取的元素。
    • 当使用Map对象(或者Map.Entry对象的集合)时,index是键,item是值。
  • 接口类

    •  //查询第1、2、3号记录的博客
        List<Blog> queryBlogForeach(Map map);
      
  • 对应xml

    •   <!--我们现在传递一个万能的map,这map中可以存在一个集合!-->
       <select id="queryBlogForeach" parameterType="map" resultType="blog">
           select * from  blog_1
           <where>
           <foreach collection="ids" item="id" open="and ("  close=")" separator="or">
                 id=#{id}
           </foreach>
           </where>
       </select>
      
  • 测试

    •  @Test
           public void testQueryBlogForeach() {
               SqlSession sqlSession = MybatisUtils.getSqlSession();
               BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
               HashMap map = new HashMap();
               ArrayList<Integer> ids = new ArrayList<Integer>();
               ids.add(1);
               ids.add(2);
               map.put("ids",ids);
               List<Blog> blogs = mapper.queryBlogForeach(map);
               for (Blog blog : blogs) {
                   System.out.println(blog);
               }
               sqlSession.close();
           }
      

12.7、SQL片段

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

  • 接口类

    • //查询博客
          List<Blog> queryBlogIf1(Map map);
      
  • 对应xml

    •  //使用SQL标签抽取公共的部分
       <sql id="if-title-author">
               <if test="title!=null">
                   title=#{title}
               </if>
               <if test="author!=null">
                    and author=#{author}
               </if>
           </sql>
       //在需要使用的地方使用include标签引用即可
       <select id="queryBlogIf1" parameterType="map" resultType="blog">
               select * from blog
               <where>
                   <include refid="if-title-author"></include>
               </where>
           </select>
      
  • 测试

    •  @Test
           public void testQueryBlogIf1() {
             //同前
           }
      
  • 注意事项

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


这篇关于Mybatis之动态SQL的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程