#6.3 輔助標籤使用java
示例1:sql
<selectSet id="getUserList" dsKey="ds" txRef="tx_01"> select * from user where 1 = 1 <if test="{user_name} != null"> and user_name LIKE concat('%',#{user_name},'%') </if> <if test="{start_time}!=null AND {start_time} !='' "><![CDATA[ and #{start_time} > create_time ]]></if> <if test="{end_time}!=null AND {end_time} != '' "><![CDATA[ and #{end_time} < create_time ]]></if> ORDER BY id DESC limit #{start}, #{pageSize} </selectSet>
說明數組
示例1是一個經典條件組合查詢場景,咱們能夠經過if標籤的test屬性判斷用戶是否輸入了某個查詢條件字段,以便拼接成一條完成的SQL語句。url
示例2:設計
<sql-service id="updateUser" dsKey="ds" txRef="tx_02"> <update rowCount="{nCount}"> update order set state = 20 where id = #{id} AND state = 10 </update> <if test="{nCount} == 1"> <insert> insert into log(context) values('訂單狀態更新成功'); </insert> </if> </sql-service>
說明code
示例2是一個條件判斷場景,若是update操做成功(根據影響行數判斷),則執行後續的插入操做。對象
示例3:索引
<sql-service id="updateUser" dsKey="ds" txRef="tx_02"> <selectVar resultKey="{type}"> select type from user where id = #{id} </selectVar> <if test="{type} == 1"> <insert> insert into log(context) values('訂單狀態更新成功'); </insert> </if> <elseif test="{type} == 2"> <update> update order set state = 20 where id = #{id} AND state = 10 </update> </elseif> <else> <delete> delete from user where where id = #{id} </delete> </else> </sql-service>
說明圖片
示例3使用if, elseif, else標籤,根據type值的不一樣,進入不一樣的處理流程。內存
Schema設計圖
test表達式說明
表達式的格式
簡單表達式:test="A Operator B"
複雜表達式:test="A Operator B [AND|OR] C Operator D"
其中A/B/C/D爲比較對象,能夠爲變量,也可爲常量;Operator爲操做符,支持如下幾種:
SN | 表達式 | 含義 | XML中的書寫格式 |
---|---|---|---|
1 | == | 等於 | == |
2 | != | 不等 | != |
3 | > | 大於 | > |
4 | >= | 大於等於 | >= |
5 | < | 小於 | < |
6 | <= | 小於等於 | <= |
7 | AND | 與 | AND |
8 | OR | 或 | OR |
注意
*1.其中1-6用在比較對象和比較對象之間,7,8用在表達式組之間。
2.在使用複雜表達式的時候,只能選擇一種關係[AND|OR],不能混合使用。
3.比較對象數據類型分爲4種:
1. NULL 2. 數值包裝類型(Byte、Short、Integer、Long、Float、Double) 3. String類型 4. 對象類型
其中比較對象的類型須要注意一下,NULL能夠和全部類型比較,String和String之間使用equals比較,數值包裝類型之間是比較其值,對象之間比較是比較其內存地址。
4.變量使用{xxx}的方式。
5.在使用3,4,5,6操做符的時候,須要使用XML實體字符,如上面表格中所給出的。
示例1:
<sql-service id="insert1" dsKey="ds" txRef="tx_02"> <insert> INSERT INTO resources( sn_id, type, title, url, create_time ) VALUES <foreach collection="{urlList}" index="{i}" separator=","> (#{sn}, 2, #{urlList[i].title}, #{urlList[i].url}, #{create_time|now()}) </foreach> </insert> </sql-service>
執行結果:
INSERT INTO resources( sn_id, type, title, url, create_time ) VALUES ('123x', 2, '圖片1', 'http://p1.sinaimg.cn/xxx', '2016-10-27 21:24:13') , ('123x', 2, '圖片2', 'http://p1.sinaimg.cn/xxx', '2016-10-27 21:24:13')
示例2:
<sql-service id="insert2" dsKey="ds" txRef="tx_02"> <foreach collection="{urlList}" index="{i}"> <insert> INSERT INTO resources( sn_id, type, title, url, create_time ) VALUES ( #{sn}, 2, #{urlList[i].title}, #{urlList[i].url}, #{create_time|now()} ) </insert> </foreach> </sql-service>
執行結果:
INSERT INTO resources( sn_id, type, title, url, create_time ) VALUES ( '123x', 2, '圖片1', 'http://p1.sinaimg.cn/xxx', '2016-10-27 21:24:13' ) INSERT INTO resources( sn_id, type, title, url, create_time ) VALUES ( '123x', 2, '圖片2', 'http://p1.sinaimg.cn/xxx', '2016-10-27 21:24:13' )
示例3:
<sql-service id="insert3" dsKey="ds" txRef="tx_02"> <selectSet> select * from resources where res_id in <foreach collection="{ids}" index="{i}" open="(" close=")" separator=","> #{ids[i]} </foreach> </selectSet> </sql-service>
執行結果:
select * from resources where res_id in ( 2 , 3 , 4 )
說明
上述三個示例表明foreach
標籤不一樣的應用場景;示例1表示組成一條批量插入語句的一部分,其包含的標籤同屬一個服務;示例2表示生成多條插入語句,多個內部服務;示例3表示組成一條in查詢的一部分,其包含的標籤同屬一個服務。
Schema設計圖
foreach
節點屬性說明
屬性名 | 用途及說明 | 必填 | 取值 |
---|---|---|---|
collection | 須要便利的集合名稱,能夠是數組、List、Set | Y | 用戶定義 |
index | 集合的索引變量,後續變量集合使用 | N | 用戶定義 |
open | 開始字符串,如insert的values部分,開始爲"(" | N | 用戶定義 |
close | 結束字符串,如insert的values部分,結束爲")", | N | 用戶定義 |
separator | 分割字符串,如insert的values部分,結束爲"," | N | 用戶定義 |
sql標籤的用途是定義一些公共的SQL語句,而include標籤是引用SQL標籤所定義的SQL語句,因此SQL標籤和include標籤是配合使用的。
示例
<sql id="getUserListWhere"> <if test="{user_name} != null"> and user_name LIKE concat('%',#{user_name},'%') </if> <if test="{start_time}!=null AND {start_time} !='' "><![CDATA[ and #{start_time} > create_time ]]></if> <if test="{end_time}!=null AND {end_time} != '' "><![CDATA[ and #{end_time} < create_time ]]></if> </sql> <sql-service id="getUserList" dsKey="ds" txRef="tx_02"> <selectVar resultKey="{total}"> SELECT count(1) from user where 1 = 1 <include ref="getUserListWhere"/> </selectVar> <selectSet> select * from user where 1 = 1 <include ref="getUserListWhere"/> ORDER BY id DESC limit #{start}, #{pageSize} </selectSet> <return> <property value="{total}"/> <property value="{projects}"/> </return> </sql-service>
說明
上述示例表示定義了兩個服務,一個是由sql標籤訂義的getUserListWhere SQL
定義,另外一個是sql-service
標籤訂義的getUserList服務,而在getUserList內部經過include
標籤引用了getUserListWhere SQL定義。
Schema設計圖
屬性說明
屬性名 | 用途及說明 | 必填 | 取值 |
---|---|---|---|
id | 標識,須要惟一,include標籤引用的時候使用。 | Y | 用戶定義 |
引用以前定義的SQL標籤的內容,至關於在本服務標籤內定義。
示例:同sql標籤示例
Schema設計圖
屬性說明
屬性名 | 用途及說明 | 必填 | 取值 |
---|---|---|---|
ref | 所引用SQL標籤的ID。 | Y | 用戶定義 |
示例1:
<selectSet> select * from ${table} where id = #{id} </selectSet>
說明:
上述示例1中出現了兩個特殊文本標識,一個是#{id}
,在以前的示例中已經屢次出現過,其含義是用戶在此處預留了一個佔位的變量,在服務調用的時候,根據用戶的傳入參數,來替換此處文本。底層的實現是經過PreparedStatement
,因此在使用的時候不會致使SQL注入的問題。通常#{xxx}
的使用場景在where後面的條件判斷、update的set賦值、insert的values部分。另外一個是${table}
, 功能大體相同,都是佔位和文本替換,區別在於${xxx}
只會單純的替換。通常用做於字段列的動態選擇、表名的替換等。
示例2:
<insert> insert into user( name, state, create_time ) values( #{name}, #{state|0}, #{create_time|now()} ); </insert>
說明:
上述示例2中又出現了一個特殊文本標識|
,他的做用是當此佔位變量用戶沒有賦值時,取|
後面的值爲默認值。下面的表格中給出的是系統支持的默認值說明:
示例 | 說明 |
---|---|
#{xxx|''} | 默認值爲空字符"" |
#{xxx|'abc'} | 默認值爲字符串"abc" |
#{xxx|0}<br />#{xxx|1.3} | 默認值爲整型,根據其值範圍決定int仍是long,此處爲int<br />默認值的類型爲浮點型,根據其值範圍決定float仍是double,此處爲float |
#{xxx|now()} | 默認值爲Java當前時間,對應java.util.Date |
#{xxx|date()} | 默認值爲Java當前時間,對應java.sql.Date |
#{xxx|time()} | 默認值爲Java當前時間,對應java.sql.Time |
#{xxx|null} | 默認值爲NULL |
其餘一些輔助標籤,涉及到組合SQL服務,因此將放在下面章節講解。