MyBatis動態SQL語法

【注:摘自MyBatis官網 】html

一、動態SQL的元素:git

二、 if語句
 
<select id="findActiveBlogWithTitleLike" resultType="Blog">
  SELECT * FROM BLOG 
  WHERE state = ‘ACTIVE’ 
  <if test="title != null">
    AND title like #{title}
  </if>
</select>
這條語句會提供一個可選的文本查找功能。若是你沒有傳遞title,那麼全部激活的博客都會被返回。可是若是你傳遞了title,那麼就會查找相近的title(對於敏銳的檢索,這中狀況下你的參數值須要包含任意的遮掩或通配符)的博客。
 
倘若咱們想可選地搜索title 和author呢?首先,要改變語句的名稱讓它有意義。而後 簡單加入另外的一個條件。
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’ 
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>
 
三、choose(when, otherwise)
 
有時咱們不想應用全部的條件, 相反咱們想選擇不少狀況下的一種。Java 中的switch和語句類似,MyBatis提供choose元素。
咱們使用上面的示例,可是如今咱們來搜索當title提供時僅有title 條件,當author提 供時僅有author條件。若是兩者都沒提供,只返回featured blogs。
 
<select id="findActiveBlogLike" 
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>
【注:choose語句中的when是隻要知足一個條件以後就放棄繼續比較了,比較方式同Java中的Switch語句相似。】
 
四、trim(where, set)
 
考慮,多個動態查詢條件狀況:
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG 
  WHERE 
  <if test="state != null">
    state = #{state}
  </if> 
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

若是這些條件都沒有匹配上將會發生什麼?這條 SQL 結束時就會成這樣:github

SELECT * FROM BLOG 
WHERE

這會致使查詢失敗。若是僅僅第二個條件匹配是什麼樣的?這條 SQL 結束時就會是這 樣:sql

SELECT * FROM BLOG 
WHERE 
AND title like ‘someTitle’

這個查詢也會失敗。這個問題不能簡單的用條件來解決,若是你歷來沒有這樣寫過,那 麼你之後也不會這樣來寫。數組

MyBatis 有一個簡單的處理,這在 90%的狀況下都會有用。而在不能使用的地方,你可 以自定義處理方式。加上一個簡單的改變,全部事情都會順利進行:mybatis

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG 
  <where> 
    <if test="state != null">
         state = #{state}
    </if> 
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>
where 元素知道若是由被包含的標記返回任意內容,就僅僅插入「WHERE」 。並且,如 果以「AND」或「OR」開頭的內容,那麼就會跳過WHERE不插入。
 
若是 where 元素沒有作出你想要的,你可使用 trim 元素來自定義。好比,和 where 元素相等的 trim元素是:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
</trim>
prefixOverrides屬性採用管道文本分隔符來覆蓋, 這裏的空白也是重要的。它的結果就是移除在prefixOverrides屬性中指定的內容,插入在with屬性中的內容。
 
和動態更新語句類似的解決方案是 set。set元素能夠被用於動態包含更新的列,而不包含不需更新的。好比:
<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>
這裏,set 元素會動態前置 SET 關鍵字,並且也會消除任意無關的逗號,那也許在應用 條件以後來跟蹤定義的值。
 
若是你對和這相等的trim元素好奇,它看起來就是這樣的:
<trim prefix="SET" suffixOverrides=",">
  ...
</trim>
注意這種狀況下咱們覆蓋一個後綴,而同時也附加前綴。
 
五、foreach
 
另一個動態SQL通用的必要操做是迭代一個集合, 一般是構建在IN條件中的。
<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select> 
foreach 元素是很是強大的,它容許你指定一個集合,聲明集合項和索引變量,它們可 以用在元素體內。它也容許你指定開放和關閉的字符串,在迭代之間放置分隔符。這個元素 是很智能的,它不會偶然地附加多餘的分隔符。
注意 你能夠傳遞一個 List 實例或者數組做爲參數對象傳給MyBatis。當你這麼作的時候,MyBatis會自動將它包裝在一個Map中,用名稱在做爲鍵。List實例將會以「list」 做爲鍵,而數組實例將會以「array」做爲鍵。
 
六、bind
 
bind元素容許你在自定義變量(不用符合OGNL規範),而且應用到上下文中。例如:
<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>
相關文章
相關標籤/搜索