mybatis学习17:动态SQL

mybatis学习17:动态SQL

  • 动态SQL:

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

    • 动态SQL常用标签:

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

       

 

  • 搭建环境:

    • 创建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;

       

    • 创建一个基础工程:

      • 导包;

      • 编写配置文件;

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE configuration
               PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
               "http://mybatis.org/dtd/mybatis-3-config.dtd">
        <configuration>

           <!--引入外部文件-->
           <properties resource="db.properties"/>

           <settings>
               <!--标准的日志工厂实现
               <setting name="logImpl" value="STDOUT_LOGGING"/>
               -->
               <setting name="logImpl" value="STDOUT_LOGGING"/>
           </settings>

           <!--添加别名-->
           <typeAliases>
               <package name="com.ljxdemo.pojo"/>
           </typeAliases>

           <environments default="development">
               <environment id="development">
                   <transactionManager type="JDBC"/>
                   <dataSource type="POOLED">
                       <property name="driver" value="${driver}"/>
                       <property name="url" value="${url}"/>
                       <property name="username" value="${username}"/>
                       <property name="password" value="${password}"/>
                   </dataSource>
               </environment>
           </environments>


           <!--注册Mapper.xml -->
           <mappers>
               <mapper resource="com/ljxdemo/dao/BlogMapper.xml"/>
           </mappers>



        </configuration>
      • 编写实体类;

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public class Blog {

           private int id;
           private String title;
           private String author;
           private Date createTime;
           private int views;

        }
      • 编写实体类对应的Mapper接口及Mapper.xml


        <!--
        注意: #{createTime} 和 create_time
        1,pojo类中需要使用驼峰命名;(createTime)
        2,Mybatis-config.xml中需要设置:mapUnderscoreToCamelCase为true
        -->
        <insert id="addBlog" parameterType="blog">
          insert into mybatis.blog (id, title, author, create_time, views) values
            (#{id},#{title},#{author},<insert id="addBlog" parameterType="blog">
              insert into mybatis.blog (id, title, author, create_time, views) values
                (#{id},#{title},#{author},#{createTime},#{views})
           </insert>,#{views})
        </insert>

         

 



 

  • 动态SQL:if 语句

    • 语法1:

      <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>
    • 语法2:

      <select id="findActiveBlogLike" resultType="Blog">
      SELECT * FROM BLOG WHERE state = ‘ACTIVE’
         
       <if test="author != null and author.name != null">
        AND author_name like #{author.name}
       </if>
         
      </select>

       

 

  • 动态SQL:choose (when, otherwise)

    • 有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用

    • 针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句

      <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>

 

 

  • 动态SQL:where

    • where元素只会在至少有一个子元素有效的情况下才插入 “where” 子句。

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

      <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>

       

 

  • 动态SQL:set

    • set元素会动态地在行首插入 SET 关键字;

    • 并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的);

    • 一般用在更新语句中;

      <update id="updateBlog" parameterType="blog">
        update blog
         <set>
             <if test="title !=null"> title=#{title},</if>
             <if test="author !=null"> author=#{author}</if>
         </set>
        where views=#{views}
      </update>
    • 注意点:

      • 如果set中所有的if条件都不满足,就会报错!

 



 

  • 动态SQL:ForEach

    • 动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候);

    • 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach

    • 当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。

    • 当使用 Map 对象时,index 是键,item 是值。

      <select id="selectPostIn" resultType="domain.blog.Post">
       SELECT *
       FROM POST P
      <where>
        <foreach item="item" index="index" collection="list"
            open="ID in (" separator="," close=")" nullable="true">
              #{item}
        </foreach>
      </where>
      </select>

      -- 例子: (id =1 or id =2 or id=3)

       SELECT * FROM POST where 1=1 and
        <foreach item="id" index="index" collection="ids"
            open="id in (" separator="or" close=")" nullable="true">
              #{item}
        </foreach>
    • mapper.xml

      <select id="queryBlogForeach" parameterType="map" resultType="blog">
        select * from blog
         <where>
             <foreach collection="ids" item="id" open="and (" separator="or" close=")">
                id=#{id}
             </foreach>
         </where>
      </select>
    • 测试:

      @Test
      public void queryBlogForeach(){
         SqlSession sqlSession = MybatisUtils.getSqlSession();
         BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

         Map reqMap = new HashMap();
         List reqList=new ArrayList();
         reqList.add(1);
         reqList.add(2);
         reqList.add(3);
         System.out.println("list:"+reqList);
         reqMap.put("ids",reqList);

         List<Blog> blogList = mapper.queryBlogForeach(reqMap);
         for (Blog blog : blogList) {
             System.out.println(blog);
        }

         sqlSession.close();

      }

 

 

  • SQL脚本片段:

    • 有的时候,我们可能会将一些公共部分抽取出来,做为复用!

    • 1,使用sql标签,抽取供部分:

      -- SQL片段语法:
      <sql id="if-title-author">
        <if test=" title !=null">
            title=#{title}
        </if>

        <if test=" author !=null">
             and author=#{author}
        </if>
      </sql>
    • 2,在需要使用的地方,使用inClude标签引用即可:

      <include refid="if-title-author"></include>
    • 注意事项:

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

      • 不要存在where标签!

 



 

  • 总结:

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

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

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

       

  • 建议:

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

 

 

 

 

  • 练习:24道练习题实战!

posted @   gzs1024  阅读(167)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示