使用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;

这是一个简单的存储过程,根据名字模糊匹配所有人员
注意:

  1. IN参数个数没有限制
  2. 如果out参数类型为sys_refcursor,那么最好只定义这 一个out参数(JPA API限制)

2.JPA调用步骤

注入JPA核心对象EntityManager

    @PersistenceContext
    private EntityManager em;

JPA定义存储过程的两种方式

  1. 基于Entity实体类,在实体类上使用注解(需要数据库中有对应的表,可自动映射结果集)
  2. 直接使用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名前缀即可
原文地址:https://www.cnblogs.com/zhuang229/p/12227938.html