[Java] Hibernate中调用Stored Procedure

博客首页 » Java Hibernate中调用Stored Procedure

发布于 09 Jun 2014 14:27
标签 blog
Hibernate中调用Stored Procedure有几种方法

1 从hibernateSession中,取得jdbc connectoin,然后调用prepareCall

http://hi.baidu.com/amauri3389/item/ab274026af6e8bcea4275a68

http://www.knowsky.com/370702.html

调用有返回值的select存储过程(用return返回,上面两种是利用参数的output属性)**
cs=conn.prepareCall("{?=call pro_select_back(?,?,?)}");
cs.registerOutParameter(1, Types.INTEGER);
cs.setString(2, "1998-02-06");
cs.setInt(3, 16);
cs.setInt(4, 33);
cs.executeQuery();
result=cs.getInt(1);
取出返回结果 ,应该是35
System.out.println(result);

2 用hibernateSession.createSQLQuery,调用 "{? = call stored_procedure(?, ?) }"

hibernateSession.createSQLQuery("{ call stored_procedure(?, ?) }");

3 用xml定义query


http://docs.jboss.org/hibernate/orm/3.5/reference/zh-CN/html/querysql.html

17.2.2. 使用存储过程来查询

Hibernate 3 引入了对存储过程查询(stored procedure)和函数(function)的支持。以下的说明中,这二者一般都适用。存储过程/函数必须返回一个结果集,作为 Hibernate 能够使用的第一个外部参数。下面是一个 Oracle9 和更高版本的存储过程例子。

CREATE OR REPLACE FUNCTION selectAllEmployments
RETURN SYS_REFCURSOR
AS
st_cursor SYS_REFCURSOR;
BEGIN
OPEN st_cursor FOR
SELECT EMPLOYEE, EMPLOYER,
STARTDATE, ENDDATE,
REGIONCODE, EID, VALUE, CURRENCY
FROM EMPLOYMENT;
RETURN st_cursor;
END;
在 Hibernate 里要要使用这个查询,你需要通过命名查询来映射它。

<sql-query name="selectAllEmployees_SP" callable="true">
<return alias="emp" class="Employment">
<return-property name="employee" column="EMPLOYEE"/>
<return-property name="employer" column="EMPLOYER"/>
<return-property name="startDate" column="STARTDATE"/>
<return-property name="endDate" column="ENDDATE"/>
<return-property name="regionCode" column="REGIONCODE"/>
<return-property name="id" column="EID"/>
<return-property name="salary">
<return-column name="VALUE"/>
<return-column name="CURRENCY"/>
</return-property>
</return>
{ ? = call selectAllEmployments() }
</sql-query>
注意存储过程当前仅仅返回标量和实体现在。不支持 <return-join> 和 <load-collection>。

17.2.2.1. 使用存储过程的规则和限制

为了在 Hibernate 中使用存储过程,你必须遵循一些规则。不遵循这些规则的存储过程将不可用。如果你仍然想使用他们,你必须通过 session.connection() 来执行他们。这些规则针对于不同的数据库。因为数据库提供商有各种不同的存储过程语法和语义。

对存储过程进行的查询无法使用 setFirstResult()/setMaxResults() 进行分页。

建议采用的调用方式是标准 SQL92: { ? = call functionName(<parameters>) } 或者 { ? = call procedureName(<parameters>) }。原生调用语法不被支持。

对于 Oracle 有如下规则:

函数必须返回一个结果集。存储过程的第一个参数必须是 OUT,它返回一个结果集。这是通过 Oracle 9 或 10 的 SYS_REFCURSOR 类型来完成的。在 Oracle 中你需要定义一个 REF CURSOR 类型,参见 Oracle 的手册。
对于 Sybase 或者 MS SQL server 有如下规则:

存储过程必须返回一个结果集。注意这些 servers 可能返回多个结果集以及更新的数目。Hibernate 将取出第一条结果集作为它的返回值,其他将被丢弃。
如果你能够在存储过程里设定 SET NOCOUNT ON,这可能会效率更高,但这不是必需的。
17.3. 定制 SQL 用来 create,update 和 delete

Hibernate3 can use custom SQL for create, update, and delete operations. The SQL can be overridden at the statement level or inidividual column level. This section describes statement overrides. For columns, see 第 5.7 节 “字段的读写表达式”.

Hibernate3 能够使用定制的 SQL 语句来执行 create,update 和 delete 操作。在 Hibernate 中,持久化的类和集合已经包含了一套配置期产生的语句(insertsql,deletesql,updatesql 等等),这些映射标记 <sql-insert>,<sql-delete> 和 <sql-update> 重载了这些语句。

<class name="Person">
<id name="id">
<generator class="increment"/>
</id>
<property name="name" not-null="true"/>
<sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert>
<sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update>
<sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete>
</class>
这些 SQL 直接在你的数据库里执行,所以你可以自由的使用你喜欢的任意语法。但如果你使用数据库特定的语法,这当然会降低你映射的可移植性。

如果设定 callable,则能够支持存储过程了。

<class name="Person">
<id name="id">
<generator class="increment"/>
</id>
<property name="name" not-null="true"/>
<sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>
<sql-delete callable="true">{? = call deletePerson (?)}</sql-delete>
<sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>
</class>
参数的位置顺序是非常重要的,他们必须和 Hibernate 所期待的顺序相同。

你能够通过设定日志调试级别为 org.hiberante.persister.entity 来查看 Hibernate 所期待的顺序。在这个级别下,Hibernate 将会打印出create,update 和 delete 实体的静态 SQL。(如果想看到预计的顺序。记得不要将定制 SQL 包含在映射文件里,因为他们会重载 Hibernate 生成的静态 SQL。)

在大多数情况下(最好这么做),存储过程需要返回插入/更新/删除的行数,因为 Hibernate 对语句的成功执行有些运行时的检查。Hibernate 常会把进行 CUD 操作的语句的第一个参数注册为一个数值型输出参数。

CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)
RETURN NUMBER IS
BEGIN

update PERSON
set
NAME = uname,
where
ID = uid;

return SQL%ROWCOUNT;

END updatePerson;


本页面的文字允许在知识共享 署名-相同方式共享 3.0协议和GNU自由文档许可证下修改和再使用,仅有一个特殊要求,请用链接方式注明文章引用出处及作者。请协助维护作者合法权益。


系列文章

文章列表

  • Java Hibernate中调用Stored Procedure

这篇文章对你有帮助吗,投个票吧?

rating: 0+x

留下你的评论

Add a New Comment