Grails探索之访问存储过程及其事务控制 .
给Grails项目配置好了数据源以后,就可以访问数据库了。Grails开发平台已经为我们配置好了Hibernate,我们可以使用GORM通过Hibernate访问数据库。这些在官方文档上有了一个初步的、详细的描述,这里就不再重述。
在很多的时候,我们会使用存储过程访问数据库,而不是使用ORM,因为存储过程对于复杂的数据库访问比起ORM有强大的优势。这就提出了一个问题,如何在Grails平台访问数据库的存储过程?
据说Hibernate为用户开放了访问存储过程的接口,但一方面我以前没有使用过Hibernate,对它不是很熟悉;另外一方面,我对GSQL的存储过程接口很感兴趣,感觉它比我以前使用的Spring的存储过程接口要好。所以,下面我将使用GSQL的存储过程接口在Grails平台来访问数据库。
我们先从简单的存储过程说起,假设我们有一个叫“PA_PPRM_PivotCar.P_Tran”的存储过程,有三个输入参数,没有输出参数。大家可以试着写一个存储过程,有包没包都没关系,这个存储过程有多个输入参数,作用是简单的insert一个table。
下面我们来访问这个存储过程。
class LoginService {
def dataSource
def check(User u) {
我们对存储过程的访问都是在service层进行的,注意声明dataSource,这样Grails平台会将dataSource对象通过Spring注入进来,我们就可以在服务层使用数据源了。
我们对存储过程的访问在check(User u)方法里,下面是代码:
Sql sql = new Sql(dataSource)
上面的代码是初始化Sql对象,记得引入该类,“import groovy.sql.Sql”,然后就可以访问存储过程了:
sql.call("call PA_PPRM_PivotCar.P_Tran(?,?,?)",['3','cheng','m'])
}
很简单,使用sql对象的call方法,第一个参数是一个字符串“call PA_PPRM_PivotCar.P_Tran(?,?,?)”,使用过Jdbc访问过存储过程的人都知道这个字符串的意思,这里不再多说。第二个参数是存储过程的输入参数,以List对象组织,按存储过程的输入顺序作为List对象元素的顺序。
就这样就完成了对存储过程的访问,是不是很简单?
下面就再进一步,我们把上面的“PA_PPRM_PivotCar.P_Tran”进行改造,给这个存储过程一个返回值,存储过程的功能还是insert一个table,因为这个table有一个主键,所以如果输入的记录主键重复的话,insert就会失败,这个存储过程的返回值就是insert成功还是失败,如果成功返回0,失败返回-1。
在这种情况下,在调用call方法之前的步骤还是和以前一样,我在这里不再重述。下面是call方法的代码:
def retn
sql.call("call PA_PPRM_PivotCar.P_Tran(?,?,?,?)",['3','cheng','m', Sql.VARCHAR]){
retn = it
}
首先定义一个变量获取返回值,即“retn”变量。可以看到,存储过程名后面跟着四个“?”,其中三个代表存储过程的输入参数,一个代表存储过程的输出参数。
call方法的第二个参数仍然是一个List对象,先按顺序给定存储过程的输入值,完了以后再按顺序给定存储过程的返回值的类型代表值,如String类型的返回值的代表值是“Sql.VARCHAR”等等。
最后通过一个闭包来获取存储过程的返回值,即:
{
retn = it
}
这样,我们获取返回值的存储过程调用就完成了。
你可能要问,如果有两个返回值怎么办?
def retn1
def retn2
sql.call("call PA_PPRM_PivotCar.P_Tran(?,?,?,?,?)",['3','cheng','m', Sql.VARCHAR, Sql.VARCHAR]){
value1,value2 ->
retn1 = value1
retn2 = value2
}
上面演示了对一个返回两个String类型值的存储过程的调用情况,可以看到,有多少个返回值,我们的闭包就有多少个输入参数,每一个参数按顺序对应一个返回值。
下面,我们再把存储过程的输出参数难道加大,我们现在有这样一个存储过程“PA_PPRM_PivotCar.P_PivotCar_GetList”,它有一个输入参数,还有一个输出参数,但这个输出参数游标。大家可以做一个简单的存储过程,用来获取一个table的所有记录,把它放在游标里返回。
下面是访问这个存储过程的代码:
sql.call("call PA_PPRM_PivotCar.P_PivotCar_GetList(?,?)",['2008',Sql.resultSet(OracleTypes.CURSOR)]){
carModel ->
carModel.eachRow(){
x ->
println"car style: ${x.carStyle},car series: ${x.carseries},car type: ${x.cartype}"
}
}
先看call方法的输入参数,第一个参数和上面的没有什么不同,第二个参数不同在于输出参数类型的代表值,为“Sql.resultSet(OracleTypes.CURSOR)”,如果是访问的是Oracle数据库的话,游标的代表值固定就是它。
最后来看闭包对返回值的处理:闭包的输入参数是一个resultset类型对象,如“ carModel”,所以要对它进行eachRow的处理,在eachRow的闭包里,我们就可以对它的输入参数x进行操作了。
在我的“PA_PPRM_PivotCar.P_PivotCar_GetList”存储过程里,游标里存的是这样一些参数:carStyle、carseries、cartype等。所以我们就可以使用“x.carStyle”、“ x.carseries”和“x.cartype”来获取它们的值了。
上面代码的输出结果为逐行打印游标每一条记录里三个参数carStyle、carseries、cartype的值。
有了上面的基础,大家可以试着做一些练习:比如存储过程返回一个String类型值和一个游标,存储过程返回两个游标等等。
简单的存储过程调用到这里就可以告一段落,现在的问题是,如果我需要调用上面的存储过程,如“PA_PPRM_PivotCar.P_Tran”多次,即我一次对一个table进行多次insert操作,怎么办?
你肯定会说,这很简单啊,对上面的call语句进行多次调用就行了,比如把上面的call语句放在一个for循环里头,不就可以了。方法是对了,但这里有一个问题,聪明的你一定想到了,“事务”。
对了,怎么控制事务呢?
下面就是一个例子:
def conn = dataSource.getConnection()
要对事务进行控制,首先要获取数据源的Connection对象,不能直接控制dataSource对象的autoCommit方法,我还没有搞清楚为什么。
然后是设置Connection对象的autoCommit为false,即由我们自己来控制事务。
conn.setAutoCommit(false)
使用Connection对象来初始化Sql对象。
Sql sql = new Sql(conn)
然后是我们属性的事务控制方法,try…catch语句。
try
{
然后调用多个存储过程。
sql.call("call PA_PPRM_PivotCar.P_Tran(?,?,?)",['3','cheng','m'])
sql.call("call PA_PPRM_PivotCar.P_Tran(?,?,?)",['1','feng','m'])
commit事务。
conn.commit()
}
catch(java.sql.SQLException e)
{
如果失败,则回滚。
conn.rollback()
throw e;
}
finally
{
最后,记得关闭Connection对象,因为dataSource对象会为你自动关闭Connection对象,但是你从dataSource对象中获取了Connection对象的话,就需要你自己关闭Connection对象。
conn.close()
}
以上就是一个简单的存储过程事务控制。大家可以写一个存储过程试试看。
分享到:
相关推荐
### Grails探索之访问存储过程及其事务控制 #### 一、引言 在Grails框架中,虽然GORM(Groovy on Rails ORM)提供了一种简单直观的方式来操作数据库,但在某些场景下,直接使用存储过程可以更好地发挥数据库的性能...
标题中提到的"Grails开发之(Rest教程)"表明本文是一份关于Grails框架下进行RESTful服务开发的教程。Grails是一个使用Groovy语言编写的高生产力的框架,其使用约定优于配置的理念,允许快速开发Web应用程序。...
Grails是一个基于Groovy语言的开源Web应用框架,它构建于Spring之上,提供了一种简化开发的方式,让开发者能够快速构建高性能的应用程序。而Spring Security(原名Acegi Security)是Spring框架的一个扩展,为Java和...
在Grails中开发RESTful API是一项常见的任务,这个文档提供了基于Grails 3.1.5版本的REST教程。Grails是一种基于Groovy语言的开源Web应用框架,它利用了Spring Boot的功能,使得构建现代互联网应用程序变得更加高效...
Grails的GSP(Groovy Server Pages)模板系统让视图层的开发更加直观,同时Grails的命令行工具能自动生成大量样板代码,如控制器、服务和视图,大大提高了开发效率。 在Grails框架中,Controllers负责处理HTTP请求...
Grails 是一个基于 Groovy 语言的开源Web应用程序框架,它构建在Java平台之上,旨在简化开发过程并提高生产力。Grails 的设计深受Ruby on Rails的影响,提供了MVC(模型-视图-控制器)架构模式,允许开发者快速构建...
2. **GORM (Grails Object-Relational Mapping)**:GORM 是 Grails 提供的持久化层,它提供了对关系数据库的简单、直观的访问。通过GORM,开发者可以使用领域驱动设计(Domain-Driven Design,DDD),定义领域模型类...
Grails 是一个基于 Groovy 语言的开源Web应用程序框架,旨在简化Web应用开发过程,提高开发效率。它借鉴了Ruby on Rails的许多设计原则,但选择了Java平台作为基础,因此可以充分利用Java生态系统中的丰富资源。...
Grails 的强大之处在于其丰富的插件库,如Spring Security用于安全控制,Hibernate Search提供全文搜索功能,以及各种用于支付、邮件发送、社交网络集成的插件,极大地扩展了框架的功能。 6. **IDE集成** ...
7. **Grails服务(Service)**:服务层在Grails中的作用,如何定义服务并进行事务管理。 8. **Grails过滤器(Filters)**:过滤器在应用程序中的应用,如何在特定的HTTP请求或响应之前/之后执行代码。 9. **Grails...
Grails 是一个基于 Java 平台的开源 web 应用框架,它采用了 Groovy 编程语言,使得开发过程更为简洁高效。`grails-doc-CN-1.0.rar` 文件包含的是 Grails 1.0 版本的中文参考文档,对于那些不熟悉英文文档或者想要...
2. `application.properties`:这个文件用于存储应用的属性,可以包含Grails Acegi插件的配置参数,如用户的认证方式、权限设置等。 3. `plugin.xml`:XML格式的插件配置文件,通常包含插件的版本、作者等信息,有时...
此外,Grails还支持AOP(面向切面编程),允许开发者通过声明式的方式处理横切关注点,如日志、事务管理等。 Grails 1.2.2在1.x系列中的改进主要体现在以下几个方面: 1. 性能优化:Grails 1.2.2对核心库进行了...
- Grails插件的概念,及其如何扩展Grails的功能和应用。 - 如何在Grails项目中查找、安装和管理插件。 7. Grails的单元测试和集成测试 - 在Grails中编写和执行单元测试和集成测试的方法。 - 测试框架的使用,...
Grails 是一个基于Groovy语言的开源Web应用框架,它构建于Java平台之上,旨在简化开发过程并提高生产力。在Grails 5.1.2这个版本中,我们看到一些关键特性和改进,这些特性有助于开发者更加高效地构建动态、灵活的...
《Grails + Spring Security 权限控制》 在Web应用开发中,权限控制是不可或缺的一环,它确保了用户只能访问他们被授权的功能和数据。本文将深入探讨如何在Grails框架中集成Spring Security,实现高效且灵活的权限...
《Grails权威指南》这本书是针对Grails框架的深度解析之作,旨在帮助开发者全面掌握Grails的使用和开发技巧。Grails是一个基于Groovy语言的开源Web应用框架,它简化了Java开发流程,提供了丰富的功能和高效能。下面...
2. MVC架构:Grails遵循Model-View-Controller(MVC)设计模式,通过GORM(Grails Object Relational Mapping)进行数据访问,使用GSP(Groovy Server Pages)作为视图模板,Controller负责业务逻辑处理。...