返回

Spring Boot 中调用带有 CLOB 输入参数的存储过程的终极指南

java

Spring Boot 中使用 CLOB 输入参数调用存储过程

问题:

在 Spring Boot 应用中,我们想要调用一个存储过程,它的第一个参数是 CLOB 输入类型。我们尝试使用 JDBC 和 Spring Data JPA,但都不成功。

解决方案:

JDBC

我们可以使用 JDBC API 来调用存储过程,并将 CLOB 参数传递进去:

try (CallableStatement function = connection.prepareCall(
                "{ call SP_SAVE_RJ_INSTANCE(?, ?, ?) }")) {
            Clob clobData = connection.createClob();
            clobData.setString(1, data);
            function.setClob(1, clobData);
            function.registerOutParameter(2, Types.NUMERIC);
            function.registerOutParameter(3, Types.VARCHAR);
            ResultSet resultSet = function.executeQuery();
        } catch (SQLException ex) {
            // handle exception
        } finally {
            connection.close();
        }

Spring Data JPA

NamedStoredProcedureQuery 方式

@NamedStoredProcedureQuery(name = "ComOwnerSeqEntity.sp_save_rj_instance",
        procedureName = "COM_OWNER.COM_PKG.sp_save_rj_instance", parameters = {
        @StoredProcedureParameter(mode = ParameterMode.IN, name = "RJCOMMONDATAIN", type = Clob.class),
        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "O_REQUESTID", type = Number.class),
        @StoredProcedureParameter(mode = ParameterMode.OUT, name = "O_ALTREQUESTID", type = String.class)})

Repository 方式

@Repository
public interface ComOwnerRepository extends JpaRepository<ComOwnerSeqEntity, Long> {
    @Procedure(name = "ComOwnerSeqEntity.sp_save_rj_instance")
   public Map<String, Object> getAlternateID(String RJCOMMONDATAIN);
}

示例代码:

// ...
ComOwnerRepository repository = ...;
String data = ...;
Map<String, Object> result = repository.getAlternateID(data);
Long requestId = (Long) result.get("O_REQUESTID");
String altRequestId = (String) result.get("O_ALTREQUESTID");
// ...

说明:

  • CLOB 输入参数使用 Clob 类型。
  • 输出参数的类型与存储过程定义的类型一致。
  • @NamedStoredProcedureQuery 方式需要在 application.properties 配置数据源。
  • @Procedure 方式用 Map 类型接收输出参数。

常见问题解答:

  1. 如何设置存储过程的参数?

    • JDBC:使用 function.setClob(1, clobData)
    • Spring Data JPA:在 @StoredProcedureParameter 注解中指定参数。
  2. 如何获取输出参数?

    • JDBC:使用 function.registerOutParameter(2, Types.NUMERIC)
    • Spring Data JPA:使用 Map 类型接收输出参数。
  3. 为什么我的代码抛出 SQLException

    • 检查存储过程的签名和参数类型是否与代码一致。
    • 确保数据库连接正确。
  4. 如何调试存储过程调用?

    • 使用 JDBC API 的 executeBatch() 方法可以捕捉异常。
    • 使用 Spring Boot 的 DataSource bean 的 setLogSlowQueries 属性启用查询日志。
  5. 如何优化存储过程调用?

    • 避免在 CLOB 参数中传递大量数据。
    • 使用批处理来减少数据库调用次数。
    • 考虑使用缓存来存储经常使用的结果。