Hibernate3.2版本对于存储过程调用的问题
最近看了hibernate3.2支持在hbm.xml文件通过<sql-query> 配置就可以进行存储过程的调用,于是便做了相关的实验
-- Create table
create table T_TEST
(
? ID?? NUMBER not null,
? NAME VARCHAR2(30),
? SEX? VARCHAR2(30),
? AGE? NUMBER
)
?
而后是hbm.xml文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
??? Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
??? <class name="test.Test" table="t_test" schema="HBM">
??????? <id name="id" column="id" type="int">
??????? ??? <generator column="name" type="string"></property>
??? ??? <property name="age" column="age" type="integer"></property>
??? ??? <property name="sex" column="sex" type="string"></property>
??? </class>
???
??? <sql-query name="getTestList" callable="true">??? <!-- function -->
??? ??? <return alias="Test" column="id"></return-property>
??? ??? ??? <return-property name="name" column="name"></return-property>
??? ??? ??? <return-property name="age" column="age"></return-property>
??? ??? ??? <return-property name="sex" column="sex"></return-property>
??? ??? </return>
??? ??? {? = call getTestList(?)} --这个是函数的调用
??? </sql-query>
???? <sql-query name="cjjtlg" callable="true">??? <!-- procedure -->
??? ??? <return alias="TTest" column="id"></return-property>
??? ??? ??? <return-property name="name" column="name"></return-property>
??? ??? ??? <return-property name="age" column="age"></return-property>
??? ??? ??? <return-property name="sex" column="sex"></return-property>
??? ??? </return>
??? ??? {call cjjtlg(?,?) }--存储过程的调用,这里如果写成帮助文档里面{?=call cjjtlg(?,?) }那必然是报告错误。
??? </sql-query>
???
??? <sql-query name="singleout" callable="true">??? <!-- procedure -->
??? ??? <return alias="TTest" column="name"></return-property>
??? ??? </return>
??? ??? {call singleout(?,?) }--带输出参数的调用
??? </sql-query>
</hibernate-mapping>
?
?
?
Session session = HibernateSessionFactory.getSession();
Query query = session.getNamedQuery("cjjtlg");
query.setInteger(0, 1);
List<Test> list = query.list();
??? ??? for (int i = 0; i < list.size(); i++) {
??? ??? ??? final Test t = list.get(i);
??? ??? ??? System.err.println("id:" + t.getId() + ", name:" + t.getName()
??? ??? ??? ??? ??? + ", age:" + t.getAge() + ", sex:" + t.getSex());
??? ??? }
??? ??? System.err.println("count :" + list.size());
??? ??? System.err.println("----------finish----------\n");
?
对于存储过程的调用对于内嵌sql-query 这里面的,那么存储过程第一个参数必须是一个结果结,且必须是一个输出参数
那么才可以使用,特别注意到时候在进行query设置的时候参数忽略第一个参数,序列号从0开始,好比query.setInteger(0, 1);如此
存储过程如下
create or replace procedure cjjtlg(st_cursor out SYS_REFCURSOR,rowsid integer) is
begin
???? open st_cursor for select * from t_test t where t.id=rowsid;
end cjjtlg;
query.setInteger(0, 1); 这个设置代表rowsid 这个参数是1,这点特别要注意。
?
如果很多读者要返回单个结果集,或者是执行某个存储过程想完成某个事项,返回参数不需要返回整个结果集,如果还想采用如此的方式进行,可以采用如下的方式来进行,只是在存储过程当中进行一些调整。
create or replace procedure singleout(st_cursor out SYS_REFCURSOR,rowsid integer) is
?temp_a varchar2(100);
begin
???? --open st_cursor for select * from t_test t where t.id=rowsid;
???? select t.sex into temp_a from t_test t where t.id = rowsid;
???? open st_cursor for select temp_a as name,1 as id,1 as age,'man' as sex from dual;
end singleout;
这样的话,其他的调用方式跟上面一样的。
1 楼 coollifer 2011-04-10 不错,关注老曹