直接使用JDBC一個非常普遍的問題就是動態SQL。使用參數值、參數本身和資料列都是動態SQL,通常是非常困難的。典型的解決辦法就是用上一堆的IF-ELSE條件陳述式和一連串的字串串連。對於這個問題,Ibatis提供了一套標準的相對比較清晰的方法來解決一個問題,這裡有個簡單的例子:
<select id="getUserList" resultMap="user">
select * from user
<isGreaterThan prepend="and" property="id" compareValue="0">
where user_id = #userId#
</isGreaterThan>
order by createTime desc
</select>
上面的例子中,根據參數bean“id”屬性的不同情況,可建立兩個可能的語句。如果參數“id”大於0,將建立下面的語句:
select * from user where user_id = ? order by createTime desc
或者,如果“id”參數小於等於0,將建立下面的語句:
select * from user order by createTime desc
以上的這個例子是否可以看出Ibatis裡提供的簡單的寫法來實現了複雜拖遝的動態SQL呢?我們在做查詢的時候,對於同一個表,甚至可以用來定義一個動態SQL,做到重用的地步,還是上面那個例子:
<sql id="queryCondition">
<dynamic prepend="WHERE">
<isGreaterThan prepend="and" property="id" compareValue="0">
where user_id = #userId#
</isGreaterThan>
</dynamic>
</sql>
<select id="getUserList" resultMap="user">
select * from user
<!-- 引入動態查詢條件 -->
<include refid="queryCondition"/>
order by createTime desc
</select>
這個使用的話是否更加的具有公用效能,這就是Ibatis帶來的便利。
在Ibatis中,動態條件元素包含一下幾種:二元條件元素、一元條件元素和其他條件元素:
(1)、二元條件元素:將一個屬性值和靜態值或另一個屬性值比較,如果條件為真,元素將被包容在查詢SQL語句中。
二元條件元素的屬性:
perpend——可被覆蓋的SQL語句組成部分,添加在語句的前面(可選)
property——是比較的屬性(必選)
compareProperty——另一個用於和前者比較的屬性(必選或選擇compareValue)
compareValue——用於比較的值(必選或選擇compareProperty)
<isEqual> |
比較屬性值和靜態值或另一個屬性值是否相等。 |
<isNotEqual> |
比較屬性值和靜態值或另一個屬性值是否不相等。 |
<isGreaterThan> |
比較屬性值是否大於靜態值或另一個屬性值。 |
<isGreaterEqual> |
比較屬性值是否大於等於靜態值或另一個屬性值。 |
<isLessThan> |
比較屬性值是否小於靜態值或另一個屬性值。 |
<isLessEqual> |
比較屬性值是否小於等於靜態值或另一個屬性值。 |
舉個小例子:
<isLessEqual prepend=”AND” property=”age” compareValue=”18”>
ADOLESCENT = ‘TRUE’
</isLessEqual>
如果大於等18歲時,則為成年人
(2)、一元條件元素:一元條件元素檢查屬性的狀態是否符合特定的條件。
一元條件元素的屬性:
prepend——可被覆蓋的SQL語句組成部分,添加在語句前面(可選)
property——被比較的屬性(必選)
<isPropertyAvailable> |
檢查是否存在該屬性(存在parameter bean的屬性) |
<isNotPropertyAvailable> |
檢查是否不存在該屬性(不存在parameter bean的屬性) |
<isNull> |
檢查屬性是否為null |
<isNotNull> |
檢查屬性是否不為null |
<isEmpty> |
檢查Collection.size()的值,屬性的String或String.valueOf()值,是否為null或空(“”或size() < 1) |
<isNotEmpty> |
檢查Collection.size()的值,屬性的String或String.valueOf()值,是否不為null或不為空白(“”或size() > 0) |
小例子:
<isNotEmpty prepend="AND" property="firstName" >
FIRST_NAME=#firstName#
</isNotEmpty>
(3)、其他元素條件
(a).Parameter Present:這些元素檢查參數對象是否存在
Parameter Present條件的屬性
prepend - 可被覆蓋的SQL語句組成部分,添加在語句的前面(可選)
<isParameterPresent> |
檢查是否存在參數對象(不為null) |
<isNotParameterPresent> |
例子: <isNotParameterPresent prepend=”AND”> EMPLOYEE_TYPE = ‘DEFAULT’ </isNotParameterPresent> |
(b)、Iterate:這屬性遍曆整個集合,並為List集合中的元素重複元素體的內容。
Iterate的屬性:
prepend - 可被覆蓋的SQL語句組成部分,添加在語句的前面(可選)
property - 類型為java.util.List的用於遍曆的元素(必選)
open - 整個遍曆內容體開始的字串,用於定義括弧(可選)
close -整個遍曆內容體結束的字串,用於定義括弧(可選)
conjunction - 每次遍曆內容之間的字串,用於定義AND或OR(可選)
<iterate> |
遍曆類型為java.util.List的元素。 例子: <iterate prepend="AND" property="userNameList" open="(" close=")" conjunction="OR"> username=#userNameList[]# </iterate> 注意:使用<iterate>時,在List元素名後麵包括方括弧[]非常重要,方括弧[]將對象標記為List,以防解析器簡單地將List輸出成String。 |
以上講述了關於Ibatis的動態SQL的功能,是否覺得非常強大,並且優雅呢?那還猶豫什麼呢?行動起來。