j2ee oracle mysql_J2EE之oracle、mysql存儲過程調用

最近幾天在研究hibernate、JPA對存儲過程的調用,主要是針對有返回結果集的存儲過程的調用方法,個人感覺存儲過程是個好東西,雖然說heibernate對數據訪問封裝的比較不錯,再加上他的緩存機制,確實很多情況下足夠了,不過存儲過程還是有他的用武之地,如果能用他提高性能,為何不用....

好吧,不討論他有沒有用處,掌握了以后備用也是不錯的選擇,重點看看oracle的存儲過程調用,mysql的要簡單的多。

(一)、oracle存儲過程調用

先在pl/sql中建立一個存儲過程,代碼如下:

13c56c39ecd432219e5fe5f4d4ae5bc9.gif--創建帶有游標的包

create or replace package mypackage astype mycursoris ref cursor;endmypackage;--創建存儲過程

create or replace procedure searchUsers(user_cursor out mypackage.mycursor) is

begin

open user_cursor for select * from wyuser order by id asc;end;13c56c39ecd432219e5fe5f4d4ae5bc9.gif

建立完成以后,如果想測試,可以先看打印出來的結果測試一下,下面是我的測試代碼:

13c56c39ecd432219e5fe5f4d4ae5bc9.gif--執行存儲過程

declareoutcursor mypackage.mycursor;

myidnumber;

mydate Date;

mypasswordvarchar2(20);

mynamevarchar2(20);begindbms_output.put_line('輸出');

searchUsers(outcursor);

loopfetch outcursor intomyid,mydate, mypassword,myname;exit when outcursor%notfound;

dbms_output.put_line(myname||' '||mypassword);endloop;end;13c56c39ecd432219e5fe5f4d4ae5bc9.gif

執行后是沒有問題的,然后我們重點在如何調用。

①hibernate中調用

在hibernate中調用oracle的存儲過程,可能會繞過heibernate,直接用jdbc操作,所以,我一直在找可有什么方法可以得到connection數據庫連接,在hibernate3.0之前提供session.connection()方法可以直接獲取到連接,不過我用的是hibernate4.0這個方法已經被廢棄了,而是用dowork方式代替,下面就看看這種方式下的調用:

13c56c39ecd432219e5fe5f4d4ae5bc9.gif/*** 調用存儲過程訪問數據*/

public ListsearchProc() {final List rtnObjs = new ArrayList();try{

Session session= this.sessionFactory.openSession();

session.beginTransaction();

Work work= newWork() {public void execute(Connection cn) throwsSQLException {

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層訪問存儲過程失敗");

}returnrtnObjs;

}13c56c39ecd432219e5fe5f4d4ae5bc9.gif

返回的結果是一個Object數組集合,這樣,就可以在業務層對這個數組進行處理,可以將其實例化為需要的對象等等.....

②Spring JDBC訪問oracle存儲過程

本來想用JPA訪問存儲過程的,不過貌似對於有返回值的存儲過程JPA處理起來不夠強大,故,如法炮制,依然繞到繞過去,用SpringJDBC來處理。存儲過程依然是上面使用的那個,下面看看JAVA的調用代碼:

13c56c39ecd432219e5fe5f4d4ae5bc9.gif/*** Spring JDBC方式調用ORACLE存儲過程,返回結果集*/@Overridepublic Listsearch() {

List rtnObjs = new ArrayList();

rtnObjs= this.jdbcTemplate.execute(newCallableStatementCreator() {

@OverridepublicCallableStatement createCallableStatement(Connection con)throwsSQLException {

CallableStatement cs= con.prepareCall("{call searchUsers(?)}");

cs.registerOutParameter("user_cursor", OracleTypes.CURSOR);returncs;

}

},new CallableStatementCallback>() {

@Overridepublic ListdoInCallableStatement(CallableStatement cs)throwsSQLException, DataAccessException {

cs.execute();

ResultSet rs= (ResultSet) cs.getObject("user_cursor");

List objs = new ArrayList();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);

}returnobjs;

}

});returnrtnObjs;

}13c56c39ecd432219e5fe5f4d4ae5bc9.gif

翻看了jdbcTemplate中的方法,很多都是回調方法,而且很多大部分都可以可以返回List和List>這種類型,說實話這種結構在實際開發中很有用途,所以在上面的代碼中也按照這種方法,返回了List交給業務層可以靈活處理。上面的方法首先繼承CallableStatementCreator中創建CallableStatement的方法注冊存儲過程和定義返回類型,在CallableStatementCallback回調接口中的重寫do方法,讓之前注冊的存儲過程執行並得到起返回值,當然也可以自己寫兩個類分別繼承CallableStatementCreator接口Callable- -StatementCallback這兩個接口,實現其中的方法,然后在jdbcTemplate的execute中調用.....

(二)、mysql存儲過程調用

相對於oracle的存儲過程,mysql的存儲過程就簡單多了,這里也同樣編寫一個返回結果集的存儲過程,然后利用jdbcTemplate對其進行調用

CREATE DEFINER=`root`@`localhost` PROCEDURE`getuser`()BEGIN

select * fromwyuser;END

真是巨簡單,看看存儲過程的調用是不是也一樣簡單

13c56c39ecd432219e5fe5f4d4ae5bc9.gif/*** 調用mysql存儲過程

*

*@return

*/@Overridepublic ListgetUser() {

List rtnObjs = new ArrayList();

rtnObjs= this.getJdbcTemplate().execute("{call getuser()}",new CallableStatementCallback>() {

@Overridepublic ListdoInCallableStatement(

CallableStatement cs)throwsSQLException,

DataAccessException {

List objects = new ArrayList();

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);

}returnobjects;

}

});returnrtnObjs;

}13c56c39ecd432219e5fe5f4d4ae5bc9.gif

好吧,呵呵,調用當然還是和調用oracle的procedure方式一樣,如果是針對有參數的調用也基本上沒有一致。

CREATE DEFINER=`root`@`localhost` PROCEDURE `finduser`(in uid int)BEGIN

select * from wyuser where id=uid;END

調用代碼:

13c56c39ecd432219e5fe5f4d4ae5bc9.gif/*** 調用mysql存儲過程,根據ID查找用戶*/@Overridepublic Object[] findUser(intid) {final int uid =id;

Object[] objArr= new Object[4];

objArr= this.getJdbcTemplate().execute("{call finduser(?)}",new CallableStatementCallback() {

@OverridepublicObject[] doInCallableStatement(CallableStatement cs)throwsSQLException, 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");

}returnarr;

}

});returnobjArr;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值