MyBatis學習總結(六)——強大的動態SQL

問題一:拼接複雜sql語句存在哪些問題?java

        經過前面對mybatis的學習能夠知道,mybaits在mapping文件中是須要寫sql語句的,可是寫sql語句的時候不可避免的會進行拼接sql語句;同時拼接過程當中可能會出現 where  1=1 and id=#{id}相似的語句,而1=1這語句是爲了不出現 where and where  1=1 and id=#{id} 的錯誤語句。sql

問題二:什麼是動態sql語句?數組

     對於解決拼接sql語句出現的問題,可能有不少小技巧或方法,好比利用1=1,可是有些問題增長了調試的複雜度,不利於開發,並且小問題可能會致使大影響,爲此,mybatis提供了一些標籤來避免這些問題給開發帶來了方便,經過這些標籤能夠組合出更靈活的sql語句,這些標籤有:if, choose(when, otherwise), trim, where, set, foreach.mybatis

1、ifapp

    if很明顯就是判斷語句,後面確定會有個表達式來肯定是否知足條件,利用if能夠實現簡單的條件選擇,例如:ide

<!-- 根據id查詢獲得一個user對象 -->
<select id="getUsers" parameterType="int" resultType="User">
	select * from users where 1=1
	<if test="type!=null and type!=''">     AND type = #{type} </if>  
	and id=#{id}
</select>

    從示例能夠看出,if標籤的使用很簡單,他有一個test屬性,test屬性值是一串表達式,示列中的意思也很明確,就是type有值得時候增長這個查詢條件,type沒值就不用這個值作查詢條件,因此if使得動態SQL簡單方便多了。學習

2、choose(when, otherwise)spa

    choose的功能就是多選一,並且是有順序的,相似於java中if ...else if ...else的功能,when至關於if或else if,otherwise至關於else。看一個具體的實例:調試

<select id="getDocuments" parameterType="int" resultType="Document">
	select * from documents where 1=1
 <choose> <when test="title!=null"> and title=#{title} </when> <when test="content!=null"> and content=#{content} </when> <otherwise> and author="zhangsan" </otherwise> </choose> 
</select>
    在上面的列子中,按順序判斷when的條件,若是都不知足,這默認執行otherwise的內容,可是若是有一個when知足,執行其對應的內容並跳出choose。如:當title!=null知足的話,就執行and title=#{title}並跳出choose,不會執行下面的when和otherw,若是title!=null不知足,content!=null知足的話,就執行and content=#{content}並跳出choose,故choose是按順序僅且執行一個知足條件的when或都不知足後執行otherwise選項的標籤。

3、trimcode

    trim元素的主要功能是能夠在本身包含的內容前加上某些前綴或在其後加上某些後綴,前綴對應屬性是prefix,後綴對應的屬性是suffix;能夠把包含內容的首部某些內容或尾部的某些內容覆蓋,即忽略,對應的屬性是prefixOverrides和suffixOverrides;因爲trim有這樣的功能,因此咱們也能夠很是簡單的利用trim來代替where元素的功能,示例代碼以下:

<!-- 根據id查詢獲得一個user對象 -->
<select id="getUsers" parameterType="int" resultType="User">
    select * from users 
    <trim prefix="where" prefixOverrides="and |or">
	   <if test="type!=null and type!=''">  
    	       and type = #{type}  
	   </if>  
	   and id=#{id}
    </trim>
</select>

4、where

    這裏的where標籤其功能就是處理(替代)sql語句中的where條件,where標籤會智能的處理where條件語句。示列代碼以下:

<select id="getDocuments" parameterType="int" resultType="Document">
	select * from documents 
	<where> <if test="title!=null"> and title=#{title} </if> <if test="content!=null"> and content=#{content} </if> </where>  
</select>
    where標籤會在咱們的sql中增長where子句部分,同時會智能處理後面的內容,好比去掉第一個and,組合條件語句中會添加標準的空格等,若是裏面的全部條件都不知足,也不影響程,會智能去掉where並查詢出所有內容。因此where標籤在多條件選擇性查詢的時候是至關有用的,不會像之前拼sql語句那麼麻煩了啊。

5、 set

    set標籤主要使用在update的操做上,其功能和where是差很少的,利用set便籤,能夠忽略sql中set語句後的逗號,也能夠利用判斷語句if來避免一些空值的複製操做,具體看下示列:

<update id="updateDocuments" parameterType="int" >
 update  documents 
 <set>           <if test="title!=null">                title=#{title},         </if>         <if test="content!=null">                content=#{content},         </if>          <if test="author!=null">               author="zhangsan"         </if>   </set>
 where id = #{id}  
</update>
    這種使用仍是很簡單的,就是將sql語句中的set字段換成一對set標籤,可是當set標籤中的全部test都不知足的狀況下,就沒有set操做了,這種狀況下是會報錯的啊。

6、foreach

    foreach標籤主要是用於構建sql中的in條件,它能夠將傳入的集合參數迭代執行造成sql中的in條件。配合foreach完成迭代的還有一些列屬性,這些屬性有item,index,collection,open,separator,close。item 是每一次迭代的一個變量名,是對集合中每個元素的一個別名,方便後面使用這個別名; index是迭代對象在集合中的下標位置(序號),是可選屬性;open表示該語句以什麼開始,好比左括號),是可選屬性;separator表示在每次進行迭代之間以什麼符號做爲元素的分隔符,好比逗號,是可選屬性;close表示以什麼結束,好比右括號),是可選屬性;collection屬性是foreach標籤中很重要的必需屬性,同時也是使用最容易出錯誤的屬性,它的使用狀況比較多,主要是如下三種狀況:

    1.collection屬性值爲list:調用mybatis接口傳入的是單個參數而且是list類型的。
    2.collection屬性值爲數組Array:調用mybatis的接口傳入的是單個參數而且是array數組類型的。
    3.collection屬性值爲map的key鍵:調用mybatis的接口傳入由一個map包含的多個參數,其實在正常狀況下傳入單個參數,在MyBatis裏面也是會把它封裝成一個Map的,map的key就是參數名,因此這個時候collection屬性值就是傳入的List或array對象在本身封裝的map裏面的key。
    上面三種狀況對應的映射配置內容以下:
    a.單個list的配置
<select id="getUsers" resultType="User">
        select * from userswhere id in <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach>
</select>

    在java代碼程序中調用mybatis的接口示列以下:

public List<User> getUsers(List<String> ids);

    b.單個數組array的配置

<select id="getUsers" resultType="User">
	select * from users where id in <foreach collection="array" index="index" item="id" open="(" separator="," close=")"> #{id} </foreach>
</select>
    在java代碼程序中調用mybatis的接口示列以下:
public List<User> getUsers(String[] ids);
     c.多參數map的配置
<select id="getUsers" resultType="User">
	select * from users where id in <foreach collection="ids" index="index" item="id" open="(" separator="," close=")"> #{id} </foreach>
</select>
     在java代碼程序中調用mybatis的接口示列以下:
public List<User> getUsers(Map<String,Object> option);