前提
想要使用JPA調用存儲過程,需要使用JPA2.1以上,API詳情點擊 此處
數據庫使用 Oracle12
JPA實現為 Hibernate
用法
1.定義存儲過程
create or replace procedure
findPerson(param in string, cur_search_result out sys_refcursor)
as
begin
open cur_search_result for
select p.* from persons p where u.name like param;
end findPerson;
這是一個簡單的存儲過程,根據名字模糊匹配所有人員
注意:
- IN參數個數沒有限制
- 如果out參數類型為sys_refcursor,那么最好只定義這 一個out參數(JPA API限制)
2.JPA調用步驟
注入JPA核心對象EntityManager
@PersistenceContext
private EntityManager em;
JPA定義存儲過程的兩種方式
- 基於Entity實體類,在實體類上使用注解(需要數據庫中有對應的表,可自動映射結果集)
- 直接使用EntityManager進行自定義(不需要數據庫中有對應的表,需要自己處理結果集)
此處使用第2種方式,直接使用EntityManager進行自定義:
- 創建StoredProcedureQuery對象,注冊 IN/OUT 參數模式
- sys_refcursor 類型的 out 參數,統一注冊為 Void.class 類型,參數模式定義為 ParameterMode.REF_CURSOR
StoredProcedureQuery procedureQuery = em.createStoredProcedureQuery("findPerson");
procedureQuery.registerStoredProcedureParameter("param", String.class, ParameterMode.IN);
procedureQuery.registerStoredProcedureParameter("cur_search_result", Void.class, ParameterMode.REF_CURSOR);
調用存儲過程,獲取結果集
- 由於out參數為sys_refcursor類型,JPA會將結果放在一個list中,list中的元素為Object[]
- 一個 Object[] 為 一行數據,一個Object[]中的數組元素為 一列數據
procedureQuery.execute();
List searchRowList = procedureQuery.getResultList();
至此,就能使用JPA調用存儲過程獲取到多行數據,后續對Object[]的和實體類之間的轉化,這里不再贅述
如果確實想要使用自動映射功能,請使用JPA定義存儲過程的 第一種方式
總結
- 在JPA中,如果out參數類型為sys_refcursor,那么最好只定義這 一個out參數
- 使用#getResultList()方法獲取游標fetch到的多行數據,返回結果為List<Object[]>,一個Object[]對應一行數據
- 如果使用Oracle package,只需在定義存儲過程名字時加個對應的package名前綴即可