日期:2014-05-16  浏览次数:20327 次

oracle存储过程备忘以及在Hibernate中使用存储过程
   Oracle存储过程主要用来处理复杂业务逻辑,把应用系统中的这些逻辑(代码,如java形式)放到数据库(pl/sql形式)中执行。可以通过存储过程来执行批量更新。存储过程直接在数据库中运行,执行效率更高。
    在Oracle数据库中可以定义一个名为batchUpdateStudent()的存储过程,代码如下:
create or replace procedure batchUpdateStudent(p_age in number) as
begin
update STUDENT set AGE=AGE+1 where AGE>p_age;
end;

   以上存储过程有一个参数p_age,代表学生的年龄,应用程序可按照以下方式调用存储过程:
//hibernater 不支持直接更新或删除的存储过程,可以绕过Hibernate,
//而在Hibernate中直接使用JDBC

tx = session.beginTransaction();
Connection con=session.connection();

String procedure = "{call batchUpdateStudent(?) }";
CallableStatement cstmt = con.prepareCall(procedure);
cstmt.setInt(1,0); //把年龄参数设为0
cstmt.executeUpdate();
tx.commit();


  使用存储过程来查询  
   Hibernate3引入了对存储过程查询的支持。存储过程必须返回一个结果集,作为Hibernate能够使用的第一个外部参数。下面是一个Oracle9i和更高版本的存储过程例子。
   
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> 
<hibernate-mapping package="com.unmi.vo"> <class name="Test" table="TEST"/>       

<sql-query callable="true" > 

<return alias="aa" > <return-property name="oborqt" column="OBORQT"/>

<return-property column="MOORQT"/> <return-property name="roschn" column="ROSCHN"/>

<return-property column="PLANDATE"/> 

<return> { ? = call selectAllUsers() } </sql-query> 

</hibernate-mapping>



   { ? = call selectAllUsers() } 也可以写成{ call selectAllUsers() }, 如果有参数就写成 { ? = call selectAllUsers(?,?,?) } 代码中对query设置相应位置上的值就OK Java调用关键代码如下
Session session = HibernateUtil.currentSession();

Query query = session.getNamedQuery("selectAllUsers"); 

List list = query.list();

System.out.println(list);


   要求你的存储过程必须能返回记录集,否则要出错 如果你的存储过程是完成非查询任务就应该在配置文件用以下三个标签
<sql-insert callable="true">{call createPerson (?, ?)}</sql-insert>

<sql-delete callable="true">{? = call deletePerson (?)}</sql-delete> 

<sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>