【注:摘自MyBatis官網 】
1、動態SQL的元素:
<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>
有時我們不想應用所有的條件, 相反我們想選擇很多情況下的一種。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語句類似。】
考慮,多個動態查詢條件情況:
<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 結束時就會成這樣:
SELECT * FROM BLOG
WHERE
這會導致查詢失敗。如果僅僅第二個條件匹配是什么樣的?這條 SQL 結束時就會是這 樣:
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’
這個查詢也會失敗。這個問題不能簡單的用條件來解決,如果你從來沒有這樣寫過,那 么你以后也不會這樣來寫。
MyBatis 有一個簡單的處理,這在 90%的情況下都會有用。而在不能使用的地方,你可 以自定義處理方式。加上一個簡單的改變,所有事情都會順利進行:
<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>
注意這種情況下我們覆蓋一個后綴,而同時也附加前綴。
另外一個動態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元素允許你在自定義變量(不用符合OGNL規范),並且應用到上下文中。例如:
<select id="selectBlogsLike" resultType="Blog"> <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" /> SELECT * FROM BLOG WHERE title LIKE #{pattern} </select>
