Oracle存儲過程主要用來處理復雜業(yè)務邏輯,把應用系統(tǒng)中的這些邏輯(代碼,如java形式)放到數(shù)據(jù)庫(pl/sql形式)中執(zhí)行??梢酝ㄟ^存儲過程來執(zhí)行批量更新。存儲過程直接在數(shù)據(jù)庫中運行,執(zhí)行效率更高。
在Oracle數(shù)據(jù)庫中可以定義一個名為batchUpdateStudent()的存儲過程,代碼如下:
- create or replace procedure batchUpdateStudent(p_age in number) as
- begin
- update STUDENT set AGE=AGE+1 where AGE>p_age;
- end;
create or replace procedure batchUpdateStudent(p_age in number) asbeginupdate STUDENT set AGE=AGE+1 where AGE>p_age;end;
以上存儲過程有一個參數(shù)p_age,代表學生的年齡,應用程序可按照以下方式調用存儲過程:
-
-
-
- tx = session.beginTransaction();
- Connection con=session.connection();
-
- String procedure = "{call batchUpdateStudent(?) }";
- CallableStatement cstmt = con.prepareCall(procedure);
- cstmt.setInt(1,0);
- cstmt.executeUpdate();
- tx.commit();
//hibernater 不支持直接更新或刪除的存儲過程,可以繞過Hibernate,//而在Hibernate中直接使用JDBCtx = session.beginTransaction();Connection con=session.connection();String procedure = "{call batchUpdateStudent(?) }";CallableStatement cstmt = con.prepareCall(procedure);cstmt.setInt(1,0); //把年齡參數(shù)設為0cstmt.executeUpdate();tx.commit();
使用存儲過程來查詢
Hibernate3引入了對存儲過程查詢的支持。存儲過程必須返回一個結果集,作為Hibernate能夠使用的第一個外部參數(shù)。下面是一個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;
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>
<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>
注意存儲過程當前僅僅返回標量和實體.現(xiàn)在不支持<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>
<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() }, 如果有參數(shù)就寫成 { ? = call selectAllUsers(?,?,?) } 代碼中對query設置相應位置上的值就OK Java調用關鍵代碼如下
- Session session = HibernateUtil.currentSession();
-
- Query query = session.getNamedQuery("selectAllUsers");
-
- List list = query.list();
-
- System.out.println(list);
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>
<sql-insert callable="true">{call createPerson (?, ?)}</sql-insert><sql-delete callable="true">{? = call deletePerson (?)}</sql-delete> <sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update>
簡單的Hibernate調用oracle存儲過程方式:
- this.pnumberManager.getHibernateTemplate().execute(
- new HibernateCallback() ...{
- public Object doInHibernate(Session session)
- throws HibernateException, SQLException ...{
- CallableStatement cs = session
- .connection()
- .prepareCall("{call modifyapppnumber_remain(?)}");
- cs.setString(1, foundationid);
- cs.execute();
- return null;
- }
- });