使用JPA调用存储过程,返回存储多行数据的OUT参数(游标)

Posted zhuang229

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用JPA调用存储过程,返回存储多行数据的OUT参数(游标)相关的知识,希望对你有一定的参考价值。

前提

想要使用JPA调用存储过程,需要使用JPA2.1以上,API详情点击 此处
数据库使用 Oracle12
JPA实现为 Hibernate

用法

定义存储过程

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限制)

JPA调用步骤

  1. 注入JPA核心对象EntityManager
    @PersistenceContext
    private EntityManager em;

JPA定义存储过程有两种方式:

  1. 基于实体类,在实体类上使用注解(需要数据库中有对应的表
  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名前缀即可

以上是关于使用JPA调用存储过程,返回存储多行数据的OUT参数(游标)的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate JPA 存储过程调用?

使用 Spring JPA 调用存储过程

如何从 Java 和 JPA 调用存储过程

存储过程和函数

Spring data jpa 调用存储过程处理返回参数及结果集

sql server 中 一个要输入参数和输出参数的存储过程。