1. 程式人生 > 其它 >mybatis學習17:動態SQL

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道練習題實戰!