Mr_Alex
Hibernate调用Oracle的存储过程

本帖最后由 Mr_Alex 于 2013-3-25 16:48 编辑

额,开头先扯点别的。。。

大家都知道在项目中过多的使用存储过程会降低应用程序的可移植性,但是为了一些这样那样的的原因,我们很多时候会不得不用到存储过程以获得较高的执行效率。虽然目前hibernate 已经添加了很多关于调用存储过程的支持,但是不得不说,还是有一些不尽人意的地方,对于对hibernate还不是很熟悉的童靴来说,这还有点难度~~所以今天跟大家分享一些关于 Hibernate调用Oracle的存储过程 的知识~

第一个存储过程:

[mw_shl_code=sql,true]

create Procedure proc()

begin

select * from proctab;

end;

[/mw_shl_code]

第二个存储过程:

[mw_shl_code=sql,true]

create procedure proc1(v_no number(4))

begin

select * from proc1

where id=v_no;

end;

[/mw_shl_code]

调用方法1:传统的 xml映射文件调用

[mw_shl_code=xml,true]

<!--xml映射文件 -->

<class name="com.test.User" table="proctab">

<id name="id" column="id">

<generator class="native"/>

</id>

<property name="name" column="name" type="string" />

<property name="age" column="age" type="integer" />

</class>

<sql-query name="getUser" callable="true">

<return alias="user" class="com.test.User">

<return-property name="id" column="id" />

<return-property name="name" column="name" />

<return-property name="age" column="age" />

</return>

{call proc()}

</sql-query>

[/mw_shl_code]

通过hibernate的API来调用以上的存储过程

[mw_shl_code=java,true]

// Hibernate API code

Session ss= HibernateSessionFactory.getSession()

List li=ss.getNamedQuery("getUser").list();

ss.close();

[/mw_shl_code]

调用方法2:通过JAVA的JDBC的API来调用

[mw_shl_code=java,true]

//jdbc 调用

Session session =HibernateSessionFactory.getSession();

Connection conn = session.connection();

ResultSet rs =null;

CallableStatement call = conn.prepareCall("{Call proc()}");

rs = call.executeQuery();

rs.close();

session.close();

[/mw_shl_code]

传递参数:

[mw_shl_code=java,true]

//传参1

CallableStatement call = conn.prepareCall("{Call proc(?)}");

call.setString(1, 参数);

rs = call.executeQuery(); [/mw_shl_code]

值得注意的是,因为这种方法是直接通过JAVA的JDBC来调用,这就破坏的hibernate的封装性,因此不被hibernate所支持,在hibernate3.3.2之前的版本中还可以通过getSession().connection()来获取一个Session对象,从而实现JDBC的调用。但是在hibernate3.3.2开始以后的版本中,hibernate就完全的丢弃了对这个方法的支持。

不过所幸的是它又提供了一个替代的方法doWork(Work work);Work是一个接口,我们可以通过实现此接口的方法,从而在其内部实现对存储过程的调用。

其实现代码如下:

[mw_shl_code=java,true]

public interface Work {

//直接通过JDBC API来访问数据库的操作

public void execute(Connection connection) throws SQLException;

}

//Session的doWork(Work work)方法用于执行Work对象指定的操作,即调用Work对象的execute()方法。Session会把当前使用的数据库连接传给execute()方法。

//过程如下:

Transaction tx=session.beginTransaction();

//定义一个匿名类,实现了Work接口

Work work=new Work(){

public void execute(Connection conn)throws SQLException{

//在这里写用JAVA的JDBC调用存储过程的方法

CallableStatement proc = null;

proc = conn.prepareCall("{ call procName(?,?,?) }");

proc.setInt(1, 100);

......

proc.execute();

......

}

};

//执行work

session.doWork(work);

tx.commit();

[/mw_shl_code]

调用方法3:直接使用hibernate的createSqlQuery调用

[mw_shl_code=java,true]

Session session =HibernateSessionFactory.getSession();

SQLQuery query = session.createSQLQuery("{Call proc()}");

List list =query.list();

session.close();

[/mw_shl_code]

hibernate的API调用时候传递参数

[mw_shl_code=java,true]

SQLQuery query = session.createSQLQuery("{Call proc(?)}");

query.setString(0, 参数);

List list =query.list();

[/mw_shl_code]

声明: 以上代码部分转自互联网,原文地址: http://www.cnblogs.com/jerryxing/archive/2012/04/28/2475762.html

写了这么多,有木有糖吃哇 @Whisper1166 @。咯咯君

该贴已经同步到 Mr_Alex的微博

one262616
one262616回复给帖子:9450549
展开Biu

好东西!!正需要!!!

[查看全文]
one262616
one262616回复给帖子:9450549
展开Biu

好东西!!正需要!!!

[查看全文]
轻舟过
狂奔的瘦子
展开Biu

狂奔的瘦子 发表于 2013-3-28 15:27

估计也是ibatis被谷歌收购以后开始的..以前的项目基本都是SSH

嗯,之前都是SSH三剑客

[查看全文]
狂奔的瘦子
其实我没有用过
展开Biu

轻舟过 发表于 2013-3-28 15:25

其实我没有用过,只是看同学们做项目都用mybatis的

估计也是ibatis被谷歌收购以后开始的..以前的项目基本都是SSH

[查看全文]
轻舟过
狂奔的瘦子
展开Biu

狂奔的瘦子 发表于 2013-3-28 15:14

主要是看什么样的项目...不过说实话hibernate确实比较臃肿

其实我没有用过,只是看同学们做项目都用mybatis的

[查看全文]
狂奔的瘦子
话说现在
展开Biu

轻舟过 发表于 2013-3-27 19:24

话说现在mybatis貌似比hibernate更流行?

主要是看什么样的项目...不过说实话hibernate确实比较臃肿

[查看全文]
轻舟过
话说现在mybatis貌似比hiberna
展开Biu

话说现在mybatis貌似比hibernate更流行?

[查看全文]
沁--茶℃
看天书一样怎么破
展开Biu

粗线,只会C和C++的飘过~看天书一样怎么破?@75#

[查看全文]