Spring Data JPA 调用 Oracle 函数

问题描述 投票:0回答:6

我正在运行一个简单的应用程序,它使用 Spring Boot + Spring Data JPA 进行持久化。

下面是一个示例 Oracle 函数,我希望在服务实现类中返回值。

CREATE OR REPLACE PACKAGE PKG_TEST AS 
  FUNCTION HELLO_WORLD(TEXT VARCHAR2) RETURN VARCHAR2;
END PKG_TEST;

CREATE OR REPLACE PACKAGE BODY PKG_TEST AS 
  FUNCTION HELLO_WORLD(TEXT VARCHAR2) RETURN VARCHAR2 IS
  BEGIN
    RETURN 'HELLO WORLD ' || TEXT;
  END;
END PKG_TEST;

在没有框架的情况下执行此操作会很简单,但该项目内置于 Spring Boot JPA 中,因此最好使用它。

我需要一个参考指南链接或简单的基础结构来遵循。 我搜索了整个 SO 和 Spring Data JPA 参考,我发现的所有示例都是针对 CRUD 和存储过程的,没有针对函数的。

我尝试使用针对函数进行修改的存储过程示例,但没有成功。

java spring oracle function jpa
6个回答
15
投票

您可以通过本机查询调用您的函数并从 Dual 中获取结果。

public interface HelloWorldRepository extends JpaRepository<HelloWorld, Long> {

    @Query(nativeQuery = true, value = "SELECT PKG_TEST.HELLO_WORLD(:text) FROM dual")
    String callHelloWorld(@Param("text") String text);

}

请注意,如果您的函数使用 DML 语句,它将不起作用。在这种情况下,您需要在查询上使用

@Modifying
注释,但由于
@Modifying
返回类型限制,函数本身必须返回数字。

您还可以实现您的

CustomRepository
并使用
SimpleJdbcCall
:

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.stereotype.Repository;

@Repository
public class HelloWorldRepositoryImpl implements HelloWorldRepositoryCustom {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public String callHelloWorld() {
        SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
                .withCatalogName("PKG_TEST") //package name
                .withFunctionName("HELLO_WORLD");
        SqlParameterSource paramMap = new MapSqlParameterSource()
                .addValue("param", "value");
        //First parameter is function output parameter type.
        return jdbcCall.executeFunction(String.class, paramMap));
    }

}

1
投票

如果您需要返回一组列,其中有 n 行从函数作为 oracle 类型返回,请使用 Table(function_name) 和 select 语句将类型解析为表并获取对象数组 List 的列表.

@Query(nativeQuery = true, value = "SELECT * FROM TABLE(ListOfStates(:country))")
List<Object[]> findStatesByCountry(@Param("country") String country);

0
投票

如果您使用 Hibernate 作为 JPA 提供程序,您可以创建自定义方言并注册所需的功能。

public class CustomDialect extends Oracle10gDialect {
    public CustomDialect() {
        super();
        // CustomFunction implements SqlFunction
        registerFunction("custom_function", new CustomFunction());
        // or use StandardSQLFunction; useful for coalesce
        registerFunction("coalesce", new StandardSQLFunction("coalesce"));
    }
}


0
投票
public interface inteface-name extends CrudRepository<Object,Long> {

    @Procedure(procedureName = "procedure-name", outputParameterName = "param-out-name")
    BigDecimal method-name(dataType input-param);
}

0
投票
 this.entityManager.getSession().doWork(connection -> {
        try (CallableStatement query = connection
                .prepareCall("BEGIN ? := FUNCTION_NAME(?); END;")) {
            query.registerOutParameter("PARAM1", Types.VARCHAR); // out param
            query.setString("PARAM2"), "SOME_VALUE"); // in param
            query.execute();
            String value = query.getString("PARAM1"); //outparam result
            System.out.println(value);
        } catch (Exception ex) {
           //process exception here
        }
    });
© www.soinside.com 2019 - 2024. All rights reserved.