一步一步學完MyBatis的動態sql標籤

寫在前面
大家好,我是Think-Coder,比較通俗的暱稱,寓意是做一個有思考的程序猿,現在的狀態是邊做項目邊學習;

博客是我平時做項目和學習的過程,很基礎,但是每一篇我很認真在寫,力求讓讀者,讀的清楚,看的明白。

不是大佬,但努力成爲,如果您也對Java、算法感興趣,可以相互關注,一起成長,相信滴水穿石的力量

一、基礎知識

動態sql是什麼

  • 動態SQL指的是事先無法預知具體的條件,需要在運行時根據具體的情況動態地生成SQL語句

動態sql作用

二、動態sql標籤總覽

在這裏插入圖片描述
參考了網上大佬的博客,開頭的博客已經涉及了前兩個分支,接着寫向下的分支

本篇博客的練習是基於之前的博客環境搭建,因爲Dao層接口和測試類大同小異,所以下面只給出映射文件中的sql語句

三、動態sql標籤詳解

3.1 控制sql語句拼接

3.1.1 if標籤

  • 如:<if test=“address != null”>,test屬性判斷address字段值是否爲空

作用

  • 用於select、insert、update語句中
  • 根據參數判斷值判斷使用哪個查詢條件,是否更新某個字段,是否插入某個字段

舉例

    <select id="findByUser" resultType="com.thinkcoder.domain.User" parameterType="com.thinkcoder.domain.User">
        select
            id,
            username,
            birthday,
            sex,
            address
        from
            user
        where
            1=1
        <if test="username !=null and username != ''"> //判斷username值是否爲空
            and username like #{username}
        </if>
        <if test="address != null">                   //判斷address值是否爲空
            and address like #{address}
        </if>
    </select>

生成的sql語句
假如username值爲空,address值不爲空

select id,username,birthday,sex,address
from user
where 1=1
and address like #{address}

3.1.2 choose|when|otherwise標籤

一般這三個標籤一起使用,相當於java中switch語句

  • choose爲switch
  • when爲case
  • otherwise爲default

標籤執行流程
在這裏插入圖片描述

Mybatis提供choose元素,按順序判斷when中條件是否成立
如果一個成立,choose結束
當when所有的條件都不滿足時,則執行otherwise中的sql語句

舉例

    <select id="findByUser" resultType="com.thinkcoder.domain.User" parameterType="com.thinkcoder.domain.User">
        select
            id,
            username,
            birthday,
            sex,
            address
        from
            user
        where
            1=1
        <choose>
            <when test="username !=null and username != ''">
                and username like #{username}
            </when>
            <when test="address != null">
                and address like #{address}
            </when>
            <otherwise>
                and sex='男'
            </otherwise>
        </choose>
    </select>

生成的sql語句
假如現在username不爲空

select id,username,birthday,sex,address
from user
where 1=1
and username like #{username}

直接拼接第一個when元素的後面的sql語句,下面的when和otherwise元素不再判斷

if和choose標籤區別

  • if可以將所有的sql語句拼接起來,choose|when|otherwise只選擇其中的一個標籤下的sql語句

3.1.3 foreach標籤

作用

  • 遍歷集合,構建in條件語句或者批量操作語句

標籤屬性

屬性 含義
collection 表示迭代集合的名稱,可以使用@Param註解指定,必選參數
item 表示本次迭代獲取元素,若collection爲List類型,表示其中元素,爲map類型表示key-value的value
open 表示語句以什麼開始,通常爲’('左括弧,可選參數
close 表示語句以什麼結束,通常爲’)'右括弧,可選參數
index List中表示當前迭代位置,Map中表示元素key,可選參數
separator 每次迭代後加的字符

參考網上大佬的博客

舉例
1.批量插入用戶
測試類代碼

    @Test
    public void  bulkInsertUser(){
        List<User> users = new ArrayList<User>();
        users.add(new User("趙一",new Date(),"男","河北邯鄲"));
        users.add(new User("錢一",new Date(),"女","河北張家口"));
        users.add(new User("孫一",new Date(),"男","河北石家莊"));

        int ids = userDao.bulkInsertUser(users);
        System.out.println(ids);//3
        //提交事務
        session.commit();
    }

IUserDao接口

    //批量添加用戶
    //參數users便爲collection屬性值
    int bulkInsertUser(@Param(value = "users") List<User> users);

IUserDao.xml映射文件

    <insert id="bulkInsertUser">
        insert into 
        	user(username,birthday,sex,address) 
        values
        <foreach collection="users" item="user" index="index" separator=",">
            (#{user.username},#{user.birthday},#{user.sex},#{user.address})
        </foreach>
    </insert>

生成的sql語句如下

   insert into 
   	   user(username,birthday,sex,address) 
   values
   	   ("趙一","2020-06-03 10:47:59","男","河北邯鄲"),
   	   ("錢一","2020-06-03 10:47:59","女","河北張家口"),
   	   ("孫一","2020-06-03 10:47:59","男","河北石家莊")

2.批量查詢用戶in語句
測試類代碼

    @Test //用於測試批量查詢用戶
    public void findInIds(){
        List<Integer> ids = new ArrayList<Integer>();
        ids.add(77);
        ids.add(78);
        
        List<User> users = userDao.findInIds(ids);
        for(User user : users){
            System.out.println(user);
        }
    }

IUserDao接口

    //批量查詢用戶
    List<User> findInIds(@Param(value = "ids") List<Integer> ids);

IUserDao.xml映射文件

    <!--批量查詢用戶-->
    <select id="findInIds" resultType="com.thinkcoder.domain.User">
        select
            id,
            username,
            birthday,
            sex,
            address
        from
            user
        <where>
            <if test="ids != null and ids.size() > 0">
                <foreach collection="ids" open = "id in (" close=")" item="id" separator=",">
                    #{id}
                </foreach>
            </if>
        </where>
    </select>

foreach迭代過程
在這裏插入圖片描述

生成的sql語句

   select
       id,
       username,
       birthday,
       sex,
       address
   from
       user
   where
   	   id in (77,78)

3.2 格式化輸出

3.2.1 where標籤

作用

  • 防止多餘關鍵字and 或 or 出現

舉例

     where
         1=1
     <if test="username !=null and username != ''"> //判斷username值是否爲空
         and username like #{username}
     </if>
     <if test="address != null">                   //判斷address值是否爲空
         and address like #{address}
     </if>

此時1=1的作用就是去掉多餘的and或or
如果不用1=1的sql語句

	where 
	and address like #{address}

where 和 and 關鍵字一起出現,此時sql語句報錯,因此就有了where標籤

where標籤例子

   select
       id,
       username,
       birthday,
       sex,
       address
   from
       user
   <where>
		<if test="username !=null and username != ''"> //判斷username值是否爲空
	       and username like #{username}
	   </if>
	   <if test="address != null">                   //判斷address值是否爲空
	       and address like #{address}
	   </if>
   </where>

除了where標籤,後面的trim標籤也可以實現

3.2.2 trim標籤

作用

  • 1.去除sql語句中多餘的關鍵字(如,and,or),逗號
  • 2.在sql語句前拼接"where"、“set”、以及"values(“等前綴,或者添加”)"等後綴

相關屬性

屬性 描述
prefix sql語句拼接的前綴
suffix sql語句拼接的後綴
prefixOverrides 去除sql語句前面的關鍵字
suffixOverrides 去除sql語句後面的關鍵字

舉例
1.去除多餘的and關鍵字

   select
       id,
       username,
       birthday,
       sex,
       address
   from
       user
   <trim prefix = "where" prefixOverrides = "and">
		<if test="username !=null and username != ''"> //判斷username值是否爲空
	       and username like #{username}
	   </if>
	   <if test="address != null">                   //判斷address值是否爲空
	       and address like #{address}
	   </if>
   </where>

prefix:加上where的前綴
prefixOverrides = “and”:覆蓋where相連的and

2.去除多餘的逗號,

   <update id="updateUser" parameterType="com.thinkcoder.domain.User">
       update user
       <trim prefix="set" suffixOverrides=",">
           <if test="username != null and username != ''">
               username = #{username},
           </if>
           <if test="sex != null and sex != ''">
               sex = #{sex},
           </if>
       </trim>
       where id=#{id}
   </update>

如果sex爲空則sql語句爲

  update user set username = #{username},where id=#{id}

此時suffixOverrides=","將set語句後的,去掉

3.2.3 Set標籤

作用

  • set標籤將多餘逗號去掉,一般用於update語句中
   <update id="updateUser" parameterType="com.thinkcoder.domain.User">
       update user
       <set>
           <if test="username != null and username != ''">
               username = #{username},
           </if>
           <if test="sex != null and sex != ''">
               sex = #{sex},
           </if>
       </set>
       where id=#{id}
   </update>

3.3 sql片段複用

  • sql標籤:重複的 sql 提取出來
  • include標籤:使用sql標籤,將重複的sql片段引用起來

舉例
sql標籤

<!-- 抽取重複的語句代碼片段 -->
<sql id="defaultSql">
	select * from user
</sql>

include標籤

<!-- 配置查詢所有操作 -->
<select id="findAll" resultType="user">
	<include refid="defaultSql"></include>
</select>

<!-- 根據 id 查詢 -->
<select id="findById" resultType="com.thinkcoder.domain.User" parameterType="int">
	<include refid="defaultSql"></include>
	where id = #{uid}
</select>

四、總結

基本的內容就總結完畢了,重點在於之後的實踐,看完之後記得自己總結下哦,總結出來的東西纔是自己的,加油

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章