#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服务,因此将放在下面章节讲解。