博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TangYuan使用教程-组合SQL服务标签
阅读量:6947 次
发布时间:2019-06-27

本文共 10666 字,大约阅读时间需要 35 分钟。

  hot3.png

#6.4 组合SQL服务标签


之前6.1节简单的介绍了组合SQL服务的概念和定义,这节将详细的介绍组合SQL服务的功能和使用。

1. sql-service标签的使用

Schema设计图

图片1

sql-service节点属性说明

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | id | 服务标识,需要唯一;作为辅助标签此项无意义,可省略 | Y | 用户定义 | | dsKey | 所使用的数据源标识,这里有以下几种情况:<br />1.此处设置数据源(A),内部服务未设置数据源,内部服务使用数据源(A)。<br />2.此处设置数据源(A),内部服务设置数据源(B),内部服务使用数据源(B)。<br />3.此处未设置数据源,内部服务设置数据源(B),内部服务使用数据源(B)。<br />4.在分库分表的情况下,此处未和内部服务均可不设置数据源,后面章节将会详细介绍此种设置。 | N | 用户定义 | | txRef | 所使用的事务定义标识,如果用户未指定,则根据setDefaultTransaction所定义的规则进行默认匹配,如果还未匹配上,系统则会跑出异常。 N 用户定义 | | resultType | 返回类型:默认xco | N | xco/map | | cacheUse | 缓存使用,此项将在缓存一节详细说明 | N | 用户定义 | | cacheClear | 缓存使用,此项将在缓存一节详细说明 | N | 用户定义 |

说明:

组合SQL服务是一个服务集合,他可以包含selectSetselectOneselectVarupdatedeleteinsert这6中基本服务标签一个或者多个,但不能包含自身sql-service标签。

2. 内部selectSet标签的使用

示例1:

select * from user

说明:

上述示例中我们定义了一个组合SQL服务myService,其内部包含了了一个selectSet基本服务,当程序执行完selectSet服务后会将其结果List<XCO>以users为key,放入上下文中,最后通过return标签返回。具体的返回结果是一个XCO对象,其中包含一个List<XCO>元素,关于return标签和返回结果的设定我们将在其他章节讲述,这里不再细说,下面给出返回结果的XML格式。

返回结果

......

上述示例中selectSet作为内部服务,或者说内部标签,其属性的使用发生了一下变化:

selectSet节点属性和变化说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | id | 无意义 | N | 用户定义 | | dsKey | 所使用的数据源标识,在有如下几种情况(非分库分表):<br />1.如果用户没有设置此属性,则使用sql-service节点的数据源;<br />2.如果用户自行设置了此属性,则使用用户所设置的数据源。<br />关于在分库分表的应用场景下,此项的设置我们将在具体的章节来说明。 | N | 用户定义 | | txRef | 无意义 | N | 用户定义 | | resultKey | 当前查询操作返回结果的在上下文参数中的存放key | N | 用户定义 | | resultType | 无意义 | N | 用户定义 | | resultMap | 无意义 | N | 用户定义 | | fetchSize | 每次查询的最大获取条数,默认255 | N | 用户定义 | | cacheUse | 缓存使用,此项将在缓存一节详细说明 | N | 用户定义 |

看到这里大家可能会疑问,和示例1中,为什么不直接用selectSet标签呢?因为之前已经给已经给大家介绍过sql-service所定义的服务是一个组合服务,其内部可以包含selectSetselectOneselectVarupdatedeleteinsert这些基本服务,在后面的教程中大家就可以感受到组合服务的强大功能了。

2. 内部selectOne标签的使用

示例2:

select * from user where user_id = #{user_id}

说明:

示例2中我们定义了一个组合SQL服务myService2,其内部包含了了一个selectOne基本服务,执行后返回结果是一个XCO对象,XML格式如下:

返回结果

selectOne节点属性和变化说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | id | 无意义 | N | 用户定义 | | dsKey | 同selectSet.dsKey | N | 用户定义 | | txRef | 无意义 | N | 用户定义 | | resultKey | 当前查询操作返回结果的在上下文参数中的存放key | N | 用户定义 | | resultType | 无意义 | N | 用户定义 | | resultMap | 无意义 | N | 用户定义 | | fetchSize | 每次查询的最大获取条数,默认255 | N | 用户定义 | | cacheUse | 缓存使用,此项将在缓存一节详细说明 | N | 用户定义 |

3. 内部selectVar标签的使用

示例3:

select user_name from user where user_id = #{user_id}

说明:

示例3中我们定义了一个组合SQL服务myService3,其内部包含了了一个selectVar基本服务,执行后返回结果是一个XCO对象,其中包含了一个userName元素,XML格式如下:

返回结果

selectVar节点属性和变化说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | id | 无意义 | N | 用户定义 | | dsKey | 同selectSet.dsKey | N | 用户定义 | | txRef | 无意义 | N | 用户定义 | | resultKey | 当前查询操作返回结果的在上下文参数中的存放key | N | 用户定义 | | cacheUse | 缓存使用,此项将在缓存一节详细说明 | N | 用户定义 |

4. 内部update标签的使用

示例4:

update user set user_name = '张三' where user_id = #{user_id}

说明:

示例4中我们定义了一个组合SQL服务myService4,其内部包含了了一个update基本服务,当程序执行完update服务后会将影响行数以nCount为key,放入上下文中,然后通过exception标签判断nCount的有效性,如果nCount不满足条件,则无服务将抛出服务异常,并回滚之前的操作。

返回结果: 无

update节点属性和变化说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | id | 无意义 | N | 用户定义 | | dsKey | 同selectSet.dsKey | N | 用户定义 | | txRef | 无意义 | N | 用户定义 | | rowCount | 当前更新操作的影响行数的在上下文参数中的存放key | N | 用户定义 | | cacheClear | 缓存使用,此项将在缓存一节详细说明 | N | 用户定义 |

5. 内部delete标签的使用

示例5:

delete from user where user_id = #{delete_user_id}

说明

示例5中我们定义了一个组合SQL服务myService5,其内部包含了了一个delete基本服务,当程序执行完delete服务后会将影响行数以nCount为key,放入上下文中,然后通过exception标签判断nCount的有效性,如果nCount不满足条件,则无服务将抛出服务异常,并回滚之前的操作。

返回结果: 无

delete节点属性和变化说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | id | 无意义 | N | 用户定义 | | dsKey | 同selectSet.dsKey | N | 用户定义 | | txRef | 无意义 | N | 用户定义 | | rowCount | 当前更新操作的影响行数的在上下文参数中的存放key | N | 用户定义 | | cacheClear | 缓存使用,此项将在缓存一节详细说明 | N | 用户定义 |

6. 内部insert标签的使用

示例6:

insert into user(user_name, user_age, create_time) values('李四', 26, #{create_time|now()});

说明:

示例6中我们定义了一个组合SQL服务myService6,其内部包含了了一个insert基本服务,当程序执行完insert服务后会作2个操作:第一,将insert语句自动生成的主键以user_id为key,放入上下文中;第二将影响行数以nCount为key,放入上下文中,然后通过return标签将其返回,XML格式如下:

返回结果

insert节点属性和变化说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | id | 无意义 | N | 用户定义 | | dsKey | 同selectSet.dsKey | N | 用户定义 | | txRef | 无意义 | N | 用户定义 | | resultType | 无意义 | N | 用户定义 | | rowCount | 当前更新操作的影响行数的在上下文参数中的存放key | N | 用户定义 | | incrementKey | 当前插入操作返回插入后的主键(数据库自动生成的)的在上下文参数中的存放key。<br />关于返回主键,有以下几种情况:<br />3.插入一条记录,返回单个主键,其结果类型视主键的数据库数据类型而定。<br />2. 插入多条记录,返回多个主键数组,数组元素类型视主键的数据库数据类型而定。 | N | 用户定义 | | cacheClear | 缓存使用,此项将在缓存一节详细说明 | N | 用户定义 |

之前我们看到的示例都是一些很简单的组合SQL服务,下面我们看一个复杂的组合SQL服务示例。

7. 组合SQL的使用

示例7

select * from user
select * from user where user_id = #{user_id}
select user_name from user where user_id = #{user_id}
update user set user_name = '张三' where user_id = #{user_id}
delete from user where user_id = #{delete_user_id}
insert into user(user_name, user_age, create_time) values('李四', 26, #{create_time|now()});

返回结果:

...

说明:

示例7其实就是整合之前的示例1到示例6,在一个服务中完成6个操作,并根据需要返回结果,就如同SQL中的存储过程,Java中的函数一般,这才是组合SQL服务的优势所在,通过一些基本服务的组合,和一些辅助标签,实现复杂的业务逻辑。使其开发人员即使不懂的JAVA也可完成大部分的服务开发工作。

8. 自定义返回结果

在组合SQL服务中可以通过return标签来定义返回内容。return标签的使用一般有下面两种情况:

示例8:

select * from user

说明:

示例8中return标签表示返回一个封装后的对象(默认为XCO类型),此对象中包含一个名为users的属性,值为List<XCO>

示例9:

select user_name from user where user_id = #{user_id}

说明:

示例9中return标签表示直接返回userName所代表的值,此处为userName的类型为String

上述两个示例说明了return标签的两种使用方式,一种是返回一个封装对象,然后通过property子标签定义其内部具体属性和属性值。另一种是直接通过return标签的value属性定义返回值,在这种情况下的返回类型由value属性中的变量所代表的值的类型来决定。注意,这两种方式不能混合使用,当然如果某个服务不需要返回类型,也可以不使用return标签,但是如果使用return标签,则只能有一个。

Schema设计图

图片2

return节点属性说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | value | 需要直接返回的变量名称, 如value="{user}" | N | 用户定义 |

property节点属性说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | name | 返回对象中的属性名称,可省略,默认为value中的变量名称 | N | 用户定义 | | value | 代表属性值的变量名称 | Y | 用户定义 |

10. log标签的使用

日志打印标签,用于在服务执行过程中的检测和日志的输出。

示例10:

...
...

说明:

上述示例中使用4个log标签,分别在update操作前后,这样开发的时候可以方便的从日志中观察到服务的执行情况。

Schema设计图

图片3

log节点属性说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | message | 日志内容,其中可使用变量;如:<log message="学生ID: {user_id}, 班级ID: {class_id}"/> | Y | 用户定义 | | level | 日志等级默认info,可参考log4j的日志等级 | N | error/warn/info/debug |

11. setvar标签的使用

用途:变量设置标签,在XML中给一个变量赋值。

示例11:

....

说明:

上述示例中先将比变量x赋值为0,然后判断条件,如果type==1,则执行selectOne操作,将执行结果重新赋值给变量x,最后返回x.

Schema设计图

图片4

setvar节点属性说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | key | 变量名称,如:key="{x}" | Y | 用户定义 | | value | 变量值 | Y | 用户定义 | | type | 变量的数据类型,默认将会根据根据用户输入变量值自动分析其类型;比如:<br />value="0",类型为int<br />value="1.3",类型为float<br />value="true",类型为boolean<br />value="xxx",类型为String<br />value="yyyy-MM-dd HH:mm:ss",类型为dateTime<br />value="yyyy-MM-dd",类型为date<br />value="HH:mm:ss",类型为time | N | int<br />long<br />float<br />double<br />short<br />boolean<br />byte<br />char<br />dateTime<br />date<br />time<br /> |

12. transGroup标签的使用

transGroup的作用就是启动一个新的事务,如果transGroup中的服务执行失败将不会影响之前的事务。

示例12:

update user set user_name = '张三' where user_id = #{user_id}
insert into user(user_name, user_age, create_time) values('李四', 26, #{create_time|now()});
update user set user_name = '李四' where user_id = #{user_id}
...

说明:

上述示例中服务执行到(1)的时候,根据transGroup所使用事务定义tx_03,启动一个新事物Y,并将之前的事务X挂起,开始执行其内部的insert服务,如果顺利的执行到(2)的位置,则提交事物Y,并恢复之前的X,继续执行后面的操作;一旦在此期间发生异常,则回滚事物Y,恢复之前的事物X,从(3)的位置继续执行。

注意:transGroup所使用的事务定义的传播属性必须是requires_new或者not_supported

Schema设计图

图片5

transGroup节点属性说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | txRef | 所引用事务定义的id | Y | 用户定义 |

13. call标签的使用

服务内部调用标签,就是在一个组合服务内部调用其他服务,可以是基本服务,也可以是另一个组合服务。

示例13A:

SELECT * from user WHERE user_id = #{user_id}
update user set user_name = '张三' where user_id = #{user_id}

说明:

上述示例中在myService内部调用了getUserById服务,调用指的是像JAVA函数之间的调用一样,有入参,有返回。当执行完call标签后,会将其执行结果以user为key放入参数上下文中。细心的同学可能会有疑问,getUserById服务是需要一个user_id参数的,如何获取其值呢?其实在上述示例中myService隐示的将自己的上下文和参数传递给getUserByIdmyService的参数中是存在user_id,所以getUserById服务可以顺利取到值。

通过下面这种方式,我们还可以显示的给getUserById服务传递参数:

示例13B:

在这中方式下,调用getUserById服务的时候仅仅给其传递了user_id一个参数。

示例13C:

说明:

示例13C中call标签出现了mode属性和exResultKey属性,mode属性表示的是调用的模式,exResultKey属性表示的是当调用发生异常后,将异常信息的codemessage封装成一个新的对象(默认为XCO对象),以ex为key放入参数上下文中,供后续程序使用。

注意: 要避免循环或递归调用。

Schema设计图

图片6

call节点属性说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | service | 被调用的服务名称。格式为:命名空间+"."+服务id | Y | 用户定义 | | resultKey | 返回结果的key | N | 用户定义 | | mode | 调用模式,默认EXTEND<br />EXTEND:被调用方将继承调用方的上下文。<br />ALONE:被调用方有独立的上下文。<br />ASYNC:异步调用,被调用方有独立的上下文。 | N | EXTEND/ALONE/ASYNC | | exResultKey | 调用过程中发生异常后,将异常信息封装成对象codemessage所存放的key | N | 用户定义 |

property节点属性说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | name | 参数名,默认为value的变量名 | N | 用户定义 | | value | 参数值 | Y | 用户定义 |

14. exception标签的使用

异常标签,当满足其检测条件的时候会抛出服务异常ServiceException

示例14:

......
......

说明:

对于exception标签的使用之前已经有过很多示例,这里我们着重介绍一些服务异常抛出后相关的处理,一般有以下几种情况:

  1. 当前上下文中运行这一个事务,对于这种情况tangyuan框架捕捉到异常后会先回滚当前事务,然后在将此异常继续上抛给调用方。对于调用方捕获到服务异常后可通过ServiceException对象的getErrorCode和getErrorMessage拿到错误码和错误描述。
  2. 当前上下文中存在挂起的事务,也就是说当前操作运行在一个独立的事务中,在这种情况下框架捕捉到异常后会先回滚当前事务,然后恢复最近挂起的服务,并继续执行。

Schema设计图

图片7

exception节点属性说明:

| 属性名 | 用途及说明 | 必填 | 取值 | | :-- | :--| :-- | :-- | | test | 逻辑表达式,同if标签的test属性。 | Y | 用户定义 | | code | 当抛出服务异常时所携带的错误码。 | N | 用户定义 | | message | 当抛出服务异常时所携带的错误描述。 | N | 用户定义 |

到此,第六章节的内容就结束了,感兴趣的朋友可以关注TangYuan项目。

  • QQ群:518522232 *请备注关注的项目
  • 邮箱:
  • 项目地址:

转载于:https://my.oschina.net/xson/blog/799084

你可能感兴趣的文章
java对象与字符串之间的序列化和反序列化
查看>>
人工智障 2 : 你看到的AI与智能无关
查看>>
Let's Encrypt 使用教程,免费的SSL证书,让你的网站拥抱 HTTPS
查看>>
.net 面试题系列四(附答案)
查看>>
sql server的并发性
查看>>
windows php启动浏览器
查看>>
CPP_类模板与模板类
查看>>
用CocoaPods做iOS程序的依赖管理
查看>>
gallery图片展示(图片间隔)
查看>>
[下一个话题]利用NodeJs+Html5+WebSocket快速构建即时在线简易PPT
查看>>
如何在Exchange Server 2007集线器传输服务器角色上使用防垃圾邮件功能
查看>>
Redis持久化相关问题
查看>>
maven-war-plugin参数说明
查看>>
Qt学习之路(18): Qt标准对话框之QInputDialog
查看>>
java中OutOfMemory种类和解决方法
查看>>
OpenNLP-Sentence Detector
查看>>
Cordova3.3在android平台下的配置方法
查看>>
ExtJs+SHH实现异步树节点搜索和查找
查看>>
go的变量作用域
查看>>
nginx 出现413 Request Entity Too Large问题的解决方法
查看>>