最近几天在研究hibernate、JPA对存储过程的调用,主要是针对有返回结果集的存储过程的调用方法,个人感觉存储过程是个好东西,虽然说heibernate对数据访问封装的比较不错,再加上他的缓存机制,确实很多情况下足够了,不过存储过程还是有他的用武之地,如果能用他提高性能,为何不用....

好吧,不讨论他有没有用处,掌握了以后备用也是不错的选择,重点看看oracle的存储过程调用,mysql的要简单的多。

(一)、oracle存储过程调用

先在pl/sql中建立一个存储过程,代码如下:

--创建带有游标的包
create or replace package mypackage as
type mycursor is ref cursor;
end mypackage; --创建存储过程
create or replace procedure searchUsers(user_cursor out mypackage.mycursor) is
begin
open user_cursor for select * from wyuser order by id asc;
end;

建立完成以后,如果想测试,可以先看打印出来的结果测试一下,下面是我的测试代码:

--执行存储过程
declare
outcursor mypackage.mycursor;
myid number;
mydate Date;
mypassword varchar2(20);
myname varchar2(20);
begin
dbms_output.put_line('输出');
searchUsers(outcursor);
loop
fetch outcursor into myid,mydate, mypassword,myname;
exit when outcursor%notfound;
dbms_output.put_line(myname||' '||mypassword);
end loop;
end;

执行后是没有问题的,然后我们重点在如何调用。
   ①hibernate中调用

在hibernate中调用oracle的存储过程,可能会绕过heibernate,直接用jdbc操作,所以,我一直在找可有什么方法可以得到connection数据库连接,在hibernate3.0之前提供session.connection()方法可以直接获取到连接,不过我用的是hibernate4.0这个方法已经被废弃了,而是用dowork方式代替,下面就看看这种方式下的调用:

    /**
* 调用存储过程访问数据
*/
public List<Object[]> searchProc() {
final List<Object[]> rtnObjs = new ArrayList<Object[]>();
try {
Session session = this.sessionFactory.openSession();
session.beginTransaction();
Work work = new Work() {
public void execute(Connection cn) throws SQLException {
CallableStatement csmt = cn
.prepareCall("{call searchUsers(?)}");
csmt.registerOutParameter("user_cursor", OracleTypes.CURSOR);
csmt.execute();
ResultSet rs = (ResultSet) csmt.getObject("user_cursor");
while (rs.next()) {
//结果用数组保存,这里只是为了测试,使用定长数组****不通用
Object[] objects = new Object[4];
objects[0] = rs.getLong("ID");
objects[1] = rs.getTimestamp("createtime");
objects[2] = rs.getString("password");
objects[3] = rs.getString("username"); rtnObjs.add(objects);
}
}
};
session.doWork(work);
session.getTransaction().commit(); } catch (Exception e) {
System.out.println("DAO层访问存储过程失败");
} return rtnObjs;
}

返回的结果是一个Object数组集合,这样,就可以在业务层对这个数组进行处理,可以将其实例化为需要的对象等等.....

②Spring JDBC访问oracle存储过程

本来想用JPA访问存储过程的,不过貌似对于有返回值的存储过程JPA处理起来不够强大,故,如法炮制,依然绕到绕过去,用SpringJDBC来处理。存储过程依然是上面使用的那个,下面看看JAVA的调用代码:

    /**
* Spring JDBC方式调用ORACLE存储过程,返回结果集
*/
@Override
public List<Object[]> search() {
List<Object[]> rtnObjs = new ArrayList<Object[]>(); rtnObjs = this.jdbcTemplate.execute(new CallableStatementCreator() { @Override
public CallableStatement createCallableStatement(Connection con)
throws SQLException {
CallableStatement cs = con.prepareCall("{call searchUsers(?)}");
cs.registerOutParameter("user_cursor", OracleTypes.CURSOR);
return cs;
}
}, new CallableStatementCallback<List<Object[]>>() { @Override
public List<Object[]> doInCallableStatement(CallableStatement cs)
throws SQLException, DataAccessException { cs.execute();
ResultSet rs = (ResultSet) cs.getObject("user_cursor");
List<Object[]> objs = new ArrayList<Object[]>();
while (rs.next()) {
Object[] objects = new Object[4];
objects[0] = rs.getLong("ID");
objects[1] = rs.getTimestamp("createtime");
objects[2] = rs.getString("password");
objects[3] = rs.getString("username"); objs.add(objects);
}
return objs;
}
}); return rtnObjs;
}

翻看了jdbcTemplate中的方法,很多都是回调方法,而且很多大部分都可以可以返回List<Object[]>和List<Map<String,Vlaue>>这种类型,说实话这种结构在实际开发中很有用途,所以在上面的代码中也按照这种方法,返回了List<Object[]>交给业务层可以灵活处理。上面的方法首先继承CallableStatementCreator中创建CallableStatement的方法注册存储过程和定义返回类型,在CallableStatementCallback回调接口中的重写do方法,让之前注册的存储过程执行并得到起返回值,当然也可以自己写两个类分别继承CallableStatementCreator接口Callable- -StatementCallback这两个接口,实现其中的方法,然后在jdbcTemplate的execute中调用.....

(二)、mysql存储过程调用

      相对于oracle的存储过程,mysql的存储过程就简单多了,这里也同样编写一个返回结果集的存储过程,然后利用jdbcTemplate对其进行调用

CREATE DEFINER=`root`@`localhost` PROCEDURE `getuser`()
BEGIN
select * from wyuser;
END

真是巨简单,看看存储过程的调用是不是也一样简单

/**
* 调用mysql存储过程
*
* @return
*/
@Override
public List<Object[]> getUser() { List<Object[]> rtnObjs = new ArrayList<Object[]>(); rtnObjs = this.getJdbcTemplate().execute("{call getuser()}",
new CallableStatementCallback<List<Object[]>>() {
@Override
public List<Object[]> doInCallableStatement(
CallableStatement cs) throws SQLException,
DataAccessException {
List<Object[]> objects = new ArrayList<Object[]>();
ResultSet rs = cs.executeQuery();
while (rs.next()) {
Object[] objArr = new Object[4];
objArr[0] = rs.getLong("ID");
objArr[1] = rs.getTimestamp("createtime");
objArr[2] = rs.getString("password");
objArr[3] = rs.getString("username"); objects.add(objArr);
}
return objects;
}
}); return rtnObjs; }

好吧,呵呵,调用当然还是和调用oracle的procedure方式一样,如果是针对有参数的调用也基本上没有一致。

CREATE DEFINER=`root`@`localhost` PROCEDURE `finduser`(in uid int)
BEGIN
select * from wyuser where id=uid;
END

调用代码:

    /**
* 调用mysql存储过程,根据ID查找用户
*/
@Override
public Object[] findUser(int id) {
final int uid = id;
Object[] objArr = new Object[4];
objArr = this.getJdbcTemplate().execute("{call finduser(?)}",
new CallableStatementCallback<Object[]>() { @Override
public Object[] doInCallableStatement(CallableStatement cs)
throws SQLException, DataAccessException {
Object[] arr = new Object[4];
cs.setInt("uid", uid); //为存储过程中参数赋值
ResultSet rs = (ResultSet) cs.executeQuery();
while (rs.next()) {
arr[0] = rs.getLong("ID");
arr[1] = rs.getTimestamp("createtime");
arr[2] = rs.getString("password");
arr[3] = rs.getString("username");
} return arr;
}
}); return objArr;
}

对于其他的方式,比如有返回值的,可以结合网上的一些案例自己再尝试下。

至此,调用这两种存储过程的方式都介绍完了,说的比较简单,呵呵,有代码有真相.....

J2EE之oracle、mysql存储过程调用的更多相关文章

  1. Mysql存储过程调用

    mysql存储过程实例教程 发布时间:2014-04-09编辑:JB01 这篇文章主要介绍了mysql存储过程的使用方法,mysql存储过程实例教程,有需要的朋友参考下.   1.1create  p ...

  2. mysql存储过程调用含out参数

    mysql 数据库有以下存储过程: CREATE DEFINER=`root`@`localhost` PROCEDURE `hovertreeTest`( IN `Param1` INT, ), O ...

  3. 创建mysql存储过程,调用 及删除

    //创建表 create table test ( aid ) primary key auto_increment , nickname ), addtime ) ) //查看表结构 show co ...

  4. mysql 存储过程调用

    CALL  存储过程名('参数值1',‘参数值2',’参数值3')

  5. MySQL存储过程中的3种循环,存储过程的基本语法,ORACLE与MYSQL的存储过程/函数的使用区别,退出存储过程方法

    在MySQL存储过程的语句中有三个标准的循环方式:WHILE循环,LOOP循环以及REPEAT循环.还有一种非标准的循环方式:GOTO,不过这种循环方式最好别用,很容易引起程序的混乱,在这里就不错具体 ...

  6. ORACLE存储过程调用Web Service

    1. 概述 最近在ESB项目中,客户在各个系统之间的服务调用大多都是在oracle存储过程中进行的,本文就oracle存储过程调用web service来进行说明.其他主流数据库,比如mysql和sq ...

  7. mysql与oracle的存储过程有什么区别?

    MySQL存储过程 (1). 格式 MySQL存储过程创建的格式:CREATE PROCEDURE过程名 ([过程参数[,...]]) [特性 ...]过程体 案例分析: 参数 MySQL存储过程的参 ...

  8. MySQL存储过程_创建-调用

    阅读目录:MySQL存储过程_创建-调用-参数 存储过程:SQL中的"脚本" 创建存储过程 调用存储过程 存储过程体 语句块标签 存储过程的参数 in:向过程里传参 out:过程向 ...

  9. MySQL存储过程的创建及调用

    阅读目录:MySQL存储过程_创建-调用-参数 存储过程:SQL中的“脚本” 1.创建存储过程 2.调用存储过程 3.存储过程体 4.语句块标签 存储过程的参数 1.in:向过程里传参 2.out:过 ...

随机推荐

  1. canvas知识点

    看到网上某些特别好看的效果,就突然想看看这个canvas; canvas是html5中的一个标签.所以兼容的是Internet Explorer 9.Firefox.Opera.Chrome 和 Sa ...

  2. py-faster-rcnn(running the demo): ubuntu14.04+caffe+cuda7.5+cudnn5.1.3+python2.7环境搭建记录

    第一次写博客,以此纪念这几天安装caffe,跑faster-rcnn的血泪史.在此特别感谢网络各路大神,来自全球各地,让我能从中汲取营养,吸取经验,总结规律. faster-rcnn分为matlab版 ...

  3. ASP.NET 常用状态(信息)保存方式

    服务器端:Session(会话)/ Application/ Caching(缓存)/DataBase(数据库) Session: Session: 常用于保存登录用户ID.验证码 不同的浏览器不能共 ...

  4. 常用的CentOS 7系统yum源集合

    常用的CentOS 7系统yum源集合   yum源对于linux系统的安装有非常大的帮助了,下面小编为各位整理了常用的CentOS 7系统yum源集合了,希望这篇文章能够对各位有所帮助的哦.   记 ...

  5. sass揭秘之@mixin,%,@function

    因为文章内含有很多sass代码,如需自己动手查看编译结果,推荐使用sassmeister这款在线编译工具,方便你阅读学习. 在阅读本文章之前,请先确认你已经阅读了上篇文章sass揭秘之变量,不然会给你 ...

  6. win8.1 64位安装DEV C++

    1.首先下载64位版本的DEV C++ http://sourceforge.net/projects/orwelldevcpp/files/Setup%20Releases/ 2.采取默认安装即可, ...

  7. visual c++ 2010安装失败导致CRM2015安装失败

    记录一下: 今天重新安装CRM2015时碰到以下错误: 安装一个或多个缺少的必备组件失败...,查看日志发现是 Microsoft Visual C++ 运行时 的安装失败,但查看系统发现vc++20 ...

  8. QPainter类的一些问题

    QPainter painter1(this);//新建类 painter1.setRenderHint(QPainter::Antialiasing,true);//设置反锯齿 painter1.s ...

  9. WCF服务一:WCF服务简介

    一.回顾开发历史: 软件架构的设计经历了:从面向对象程序,到面向组件程序设计,再到面向服务程序设计.这三种方式都致力于同一个目标:封装和重用. 面向对象程序设计:类封装功能并提供代码重用. 面向组件程 ...

  10. 向 Git 服务器添加 SSH 公钥

    . . . . . 在网上很少找到文章有提到如何将自己的 Git 远程仓库配置成可以通过 SSH 公钥方式认证的,而几乎清一色都是告诉你怎么通过 web 界面向 GitHub 添加 SSH 公钥.LZ ...