trim, where, set
前面幾個例子已經合宜地解決了一個臭名昭著的動態 SQL 問題。現在回到“if”示例,這次我們將“ACTIVE = 1”也設置成動態的條件,看看會發生什么。
SELECT * FROM BLOG
WHERE
state = #{state}
AND title like #{title}
AND author_name like #{author.name}
如果這些條件沒有一個能匹配上會發生什么?最終這條 SQL 會變成這樣:
SELECT *FROM BLOG
WHERE
這會導致查詢失敗。如果僅僅第二個條件匹配又會怎樣?這條 SQL 最終會是這樣:
SELECT *FROM BLOG
WHERE
AND title like ‘someTitle’
這個查詢也會失敗。這個問題不能簡單地用條件句式來解決,如果你也曾經被迫這樣寫過,那么你很可能從此以后都不會再寫出這種語句了。
MyBatis 有一個簡單的處理,這在 90% 的情況下都會有用。而在不能使用的地方,你可以自定義處理方式來令其正常工作。一處簡單的修改就能達到目的:
SELECT * FROM BLOG
state = #{state}
AND title like #{title}
AND author_name like #{author.name}
where?元素只會在至少有一個子元素的條件返回 SQL 子句的情況下才去插入“WHERE”子句。而且,若語句的開頭為“AND”或“OR”,where?元素也會將它們去除。
如果?where?元素沒有按正常套路出牌,我們可以通過自定義 trim 元素來定制?where?元素的功能。比如,和?where?元素等價的自定義 trim 元素為:
...
prefixOverrides?屬性會忽略通過管道分隔的文本序列(注意此例中的空格也是必要的)。它的作用是移除所有指定在?prefixOverrides?屬性中的內容,并且插入?prefix?屬性中指定的內容。
類似的用于動態更新語句的解決方案叫做?set。set?元素可以用于動態包含需要更新的列,而舍去其它的。比如:
update Author
username=#{username},password=#{password},email=#{email},bio=#{bio}where id=#{id}
這里,set?元素會動態前置 SET 關鍵字,同時也會刪掉無關的逗號,因為用了條件語句之后很可能就會在生成的 SQL 語句的后面留下這些逗號。(譯者注:因為用的是“if”元素,若最后一個“if”沒有匹配上而前面的匹配上,SQL 語句的最后就會有一個逗號遺留)
若你對?set?元素等價的自定義 trim 元素的代碼感興趣,那這就是它的真面目:
...
注意這里我們刪去的是后綴值,同時添加了前綴值。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态