使用JPA调用存储过程,返回存储多行数据的OUT参数游标
前提
想要使用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名前缀即可