• 使用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名前缀即可
  • 相关阅读:
    c++中的内存管理【转载】
    c++中dynamic_cast、static_cast、reinterpret_cast和const_cast作用
    c++中的顶层const和底层const
    c++赋值操作符需要确保自我赋值的安全性问题
    二分法查找
    Servlet基础总结
    java 正则表达式:有丶东西
    HTTP协议初步认识
    Java synchronized到底锁住的是什么?
    ECMA Script 6新特性之解构赋值
  • 原文地址:https://www.cnblogs.com/zhuang229/p/12227938.html
Copyright © 2020-2023  润新知