[Hibernate tutorial] Calling Oracle store procedure via Hibernate3

About Oracle store procedure


 

It a common usage of Dynamic SQL(动态SQL) within Oracle store procedure. We may select some data from one or more tables with dynamic where cause. For example, according to different senario, we may select data by limiting column t_users.pid.

  • select data by a.pid
SELECT * FROM t_users a, p_users b
WHERE a.pid = b.id
AND a.pid in (1,2);
  • select data with no criteria
SELECT * FROM t_users a, p_users b
WHERE a.pid = b.id

We may create a store procedure to handle dynamic range of column pid in table table1.

But it is a big difference between Oracle store procedure and SQL server procedure. For dynamic SQL in oracle, we must define a sys_refcursor in out param. SP SQL code like this:

CREATE OR REPLACE STORE PROCEDURE SP_GETDATA(
  pids in varchar2, 
  o_cursor out SYS_REFCURSOR
)
AS
    sql varchar2(1000);
BEGIN
    
    sqlstr := 'SELECT * FROM T_USERS A, P_USERS B ' ||
            ' WHERE A.PID = B.ID '

    IF pids is not null THEN
        sqlstr := sqlstr || ' AND A.PID IN (' || pids || ')';
    END IF;

    OPEN o_cursor FOR sqlstr;

END;

 

Calling a store procedure from PL/SQL :

DECLARE 
O_CURSOR SYS_REFCURSOR;
ID NUMBER;
PID NUMBER;
NAME VARCHAR2(100);
AGE NUMBER;
BEGIN
    SP_GETDATA('1,2', O_CURSOR);
    LOOP 
      FETCH O_CURSOR INTO ID, PID, NAME, AGE;
      DBMS_OUTPUT.PUT_LINE('ID: ' || ID || chr(9) || 'NAME: ' || NAME || chr(9) || 'AGE: ' || AGE);
    END LOOP;
    CLOSE O_CURSOR;
END;

 

The OUTPUT result may something like this:

ID: 1    NAME:    Enix Yu    AGE: 28
ID: 2    NAME:    Tommy    AGE: 30
......

 

To finish a dynamic select query in oracle world, you need to :

  1. define a SYS_REFCURSOR for output parameter.
  2. make a dynamic select statement according to your need.
  3. Open the cursor for the select statement.
  4. That's all.

Use Oracle store procedure in Hibernate 


1. According to the hibernate user reference manual, the store procedure must return a ResultSet as the first out-parameter to be able to work with hibernate. Therefore, we must revise the sp as below:

CREATE OR REPLACE STORE PROCEDURESP_GETDATA(
  o_cursor out SYS_REFCURSOR, -- the cursor must be the first parameter
  pids in varchar2)

AS
sql varchar2(1000);
BEGIN
    
    sqlstr := 'SELECT * FROM T_USERS A, P_USERS B ' ||
            ' WHERE A.PID = B.ID '

    IF pids is not null THEN
        sqlstr := sqlstr || ' AND A.PID IN (' || pids || ')';
    END IF;

    OPEN o_cursor FOR sqlstr;

END;

 

2. Define a store procedure in Table.hbm.xml

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.antrui.orclsp.mapping">
  <class name="TUsers" table="T_USERS" lazy="false" >
    <id name="ID" type="int">
      <column name="ID" not-null="true" />
      <generator class="sequence">      
          <param name="sequence">T_USERS_ID</param>      
      </generator>  
    </id>
    <many-to-one insert="true" update="true" lazy="false" name="P_USERS">
      <column name="PID" sql-type="NUMBER" not-null="false" />
    </many-to-one>
    <property name="NAME">
      <column name="NAME" sql-type="VARCHAR2" not-null="false" />
    </property>    
  <property name="AGE">
      <column name="AGE" sql-type="NUMBER" not-null="false" />
    </property>    
  </class>
  <sql-query name="SP_GETDATA" callable="true">
      { call SP_GETDATA(?, :pids) }  <!-- :pids is mapped to the sp 2nd parameter -->
  </sql-query>
</hibernate-mapping>

 3. Call the store procedure 'SP_GETDATA' in java

public List getEntitiesByProc(String procName, String[] columnName,  Object[] param){
  Session session = HibernateUtil.currentSession();
  List list = null;
  try {
      Query query = session.getNamedQuery(procName);
      for(int i = 0; i < param.length; i++){
        query.setParameter(columnName[i], param[i]);
      }
      list = query.list();
  }
  catch (Exception e) {
    e.printStackTrace();
  }
  finally{
    HibernateUtil.closeSession();
  }
  return list;
}

public List getData(){
  ......
  String[] columnNames = {"ID"};
  String[] values = {"1,2,3"};
  List list = getEntitiesByProc('SP_GETDATA', columnNames, values);
  ......

}

 

That's all... Thank you for reading. 

 

 

 

 

 

 

 

 

  

转载于:https://www.cnblogs.com/enixyu/archive/2012/09/10/2678647.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值