You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot使用@Query调用带REF_CURSOR的Oracle存储过程遇阻

解决Spring Boot调用Oracle带REF_CURSOR的存储过程问题

先解决ojdbc8依赖问题(手动引入)

因为无法使用Maven安装ojdbc8.jar,按以下步骤操作:

  1. 在项目根目录创建src/main/resources/lib文件夹,将ojdbc8.jar放入其中。
  2. IDE中添加jar为项目库:
    • IDEA:右键jar文件 → Add as Library,选择对应模块确认。
    • Eclipse:右键项目 → Build Path → Add External Archives,选中ojdbc8.jar。
  3. 若需要打包时包含该jar,在pom.xml中添加system scope依赖:
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>19.3.0.0</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/src/main/resources/lib/ojdbc8.jar</systemPath>
    </dependency>
    

方案1:使用Spring Data JPA的@Procedure注解(推荐)

REF_CURSOR是存储过程的输出参数,无需手动传入RefCursor对象,Spring Data可自动映射结果到实体:

修改PersonRepository:

package com.redacted.prototype1.repository;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Procedure;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import mil.af.dmcodb.prototype1.entity.Person;

@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
    
    @Transactional
    @Procedure(procedureName = "SST_JBOSS_PROTYPE_PRSN")
    List<Person> callPersonProcedure();
}

添加JPA配置到application.properties:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle12cDialect
spring.jpa.properties.hibernate.jdbc.use_get_generated_keys=true

方案2:用EntityManager手动处理存储过程(灵活定制)

如果@Procedure无法满足需求,可自定义Repository实现:

  1. 定义自定义接口:
public interface PersonCustomRepository {
    List<Person> getPersonsFromProcedure();
}
  1. 实现自定义接口:
package com.redacted.prototype1.repository.impl;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import oracle.jdbc.OracleTypes;
import mil.af.dmcodb.prototype1.entity.Person;

@Repository
public class PersonCustomRepositoryImpl implements PersonCustomRepository {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    @Transactional
    public List<Person> getPersonsFromProcedure() {
        // 注册存储过程,?对应REF_CURSOR输出参数
        javax.persistence.Query query = entityManager.createNativeQuery("{ call SST_JBOSS_PROTYPE_PRSN(?) }", Person.class);
        query.registerStoredProcedureParameter(1, void.class, javax.persistence.ParameterMode.OUT);
        query.setHint("org.hibernate.callable", true);
        query.setHint("org.hibernate.jdbc.register_ref_cursor", OracleTypes.CURSOR);
        return query.getResultList();
    }
}
  1. 修改主Repository继承自定义接口:
@Repository
public interface PersonRepository extends JpaRepository<Person, Integer>, PersonCustomRepository {
}

关键说明

  • 原代码错误在于将REF_CURSOR作为输入参数传入,实际上它是存储过程的输出参数,无需手动创建RefCursor对象。
  • 引入ojdbc8后,oracle.jdbc.OracleTypes即可正常导入,解决之前的导入错误。

内容的提问来源于stack exchange,提问作者Kmus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 17:23:46