
本帖最后由 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的微博