Spring Boot使用@Query调用带REF_CURSOR的Oracle存储过程遇阻
解决Spring Boot调用Oracle带REF_CURSOR的存储过程问题
先解决ojdbc8依赖问题(手动引入)
因为无法使用Maven安装ojdbc8.jar,按以下步骤操作:
- 在项目根目录创建
src/main/resources/lib文件夹,将ojdbc8.jar放入其中。 - IDE中添加jar为项目库:
- IDEA:右键jar文件 →
Add as Library,选择对应模块确认。 - Eclipse:右键项目 →
Build Path→Add External Archives,选中ojdbc8.jar。
- IDEA:右键jar文件 →
- 若需要打包时包含该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实现:
- 定义自定义接口:
public interface PersonCustomRepository { List<Person> getPersonsFromProcedure(); }
- 实现自定义接口:
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(); } }
- 修改主Repository继承自定义接口:
@Repository public interface PersonRepository extends JpaRepository<Person, Integer>, PersonCustomRepository { }
关键说明
- 原代码错误在于将REF_CURSOR作为输入参数传入,实际上它是存储过程的输出参数,无需手动创建RefCursor对象。
- 引入ojdbc8后,
oracle.jdbc.OracleTypes即可正常导入,解决之前的导入错误。
内容的提问来源于stack exchange,提问作者Kmus
相关产品推荐
相关产品推荐

