【问题标题】:How to call Oracle function or stored procedure using spring persistence framework?如何使用 Spring 持久化框架调用 Oracle 函数或存储过程?
【发布时间】:2010-10-26 03:35:47
【问题描述】:

我正在为我的项目使用 Spring 持久性框架。 我想从这个框架中调用 oracle 函数或存储过程。

任何人都可以建议我如何实现这一目标。

请给出 *oracle 函数和 *存储过程的解决方案。

谢谢。

【问题讨论】:

  • Spring有持久化框架吗?你指的是 Spring 的 JdbcTemplate 吗?还是休眠?
  • 我使用 DPTK 创建了持久化框架和 Spring 的查询工厂。现在想使用现有功能调用oracle函数或存储过程,你能帮我排序吗..
  • DPTK 似乎是 IBM 产品:alphaworks.ibm.com/tech/dptk
  • 我不明白与 junit 的关系。您能否提供这些信息?

标签: spring oracle junit


【解决方案1】:

假设您指的是 JdbcTemplate:

jdbcTemplate.execute(
    new CallableStatementCreator() {
        public CallableStatement createCallableStatement(Connection con) throws SQLException{
            CallableStatement cs = con.prepareCall("{call MY_STORED_PROCEDURE(?, ?, ?)}");
            cs.setInt(1, ...); // first argument
            cs.setInt(2, ...); // second argument
            cs.setInt(3, ...); // third argument
            return cs;
        }
    },
    new CallableStatementCallback() {
        public Object doInCallableStatement(CallableStatement cs) throws SQLException{
            cs.execute();
            return null; // Whatever is returned here is returned from the jdbcTemplate.execute method
        }
    }
);

调用函数几乎是一样的:

jdbcTemplate.execute(
    new CallableStatementCreator() {
        public CallableStatement createCallableStatement(Connection con) {
            CallableStatement cs = con.prepareCall("{? = call MY_FUNCTION(?, ?, ?)}");
            cs.registerOutParameter(1, Types.INTEGER); // or whatever type your function returns.
            // Set your arguments
            cs.setInt(2, ...); // first argument
            cs.setInt(3, ...); // second argument
            cs.setInt(4, ...); // third argument
            return cs;
        }
    },
    new CallableStatementCallback {
        public Object doInCallableStatement(CallableStatement cs) {
            cs.execute();
            int result = cs.getInt(1);
            return result; // Whatever is returned here is returned from the jdbcTemplate.execute method
        }
    }
);

【讨论】:

  • 这里叫SP,怎么叫Oracle Function...我不是指JdbcTemplate,我指的是使用DPTK的持久化框架..
  • 第二个例子是调用函数。不幸的是,我不熟悉 DPTK。有网站吗?
  • 好的,我会尝试用我的代码来实现它...希望它会起作用..谢谢亚当,会让你知道结果..
  • 你不必使用这个。我只是不知道 Spring 持久性框架是什么。这只是我的最佳猜测。
  • DPTK(Design Patter Tool Kit) 是一个RAD插件,可惜我现在没有它的网站,一旦得到我会发给你..
【解决方案2】:

在 Spring 中调用 Oracle 函数的更简单方法是继承 StoredProcedure,如下所示

public class MyStoredProcedure extends StoredProcedure{
    private static final String SQL = "package.function";

    public MyStoredProcedure(DataSource ds){
        super(ds,SQL);
        declareParameter(new SqlOutParameter("param_out",Types.NUMERIC));
        declareParameter(new SqlParameter("param_in",Types.NUMERIC));
        setFunction(true);//you must set this as it distinguishes it from a sproc
        compile();
    }

    public String execute(Long rdsId){
        Map in = new HashMap();
        in.put("param_in",rdsId);
        Map out = execute(in);
        if(!out.isEmpty())
            return out.get("param_out").toString();
        else
            return null;
    }
}

然后这样称呼它

@Autowired DataSource ds;
MyStoredProcedure sp = new MyStoredProcedure(ds);
String i = sp.execute(1l);

这里使用的Oracle函数只是接受一个数字参数并返回一个数字参数。

【讨论】:

  • 据我了解,SQL 代码应如下所示:{:param_out = call schema.package.MY_FUNCTION(:param_in)}
  • 我最后的评论是错误的。 SQL 常量必须只包含过程/函数名称,如 schema.package.MY_FUNCTION,以及 Java HAVE 中的参数名称,以匹配过程/函数中定义的参数名称。
【解决方案3】:

在我看来,这是最简单的方法之一:

public class ServRepository {

    private JdbcTemplate jdbcTemplate;
    private SimpleJdbcCall functionGetServerErrors;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.setResultsMapCaseInsensitive(true);
        this.functionGetServerErrors = new SimpleJdbcCall(jdbcTemplate).withFunctionName("THIS_IS_YOUR_DB_FUNCTION_NAME").withSchemaName("OPTIONAL_SCHEMA_NAME");
    }

        public String callYourFunction(int parameterOne, int parameterTwo) {
            SqlParameterSource in = new MapSqlParameterSource().addValue("DB_FUNCTION_INCOMING_PARAMETER_ONE", parameterOne).addValue("DB_FUNCTION_INCOMING_PARAMETER_TWO", parameterTwo);
            return functionGetServerErrors.executeFunction(String.class, in);
        }
}

【讨论】:

  • 为什么不new SimpleJdbcCall(dataSource)
  • @Alex78191 您需要在那里编写 SQL。我试图保持不可知论。
  • 不,其他都一样。
  • @Alex78191 您能否提供一个 SimpleJdbcCall 的示例答案?我不记得我为什么选择这个解决方案了 tbh
  • @Alex78191 有 SQL。我选择了这个解决方案,因为它是纯 Java 并且非常简单。
【解决方案4】:

使用NamedParameterJdbcTemplate调用函数:

final String query = "select MY_FUNCTION(:arg1, :arg2, :arg3) from dual";
Map<String, Object> argMap = new HashMap<>();
argMap.put("arg1", "value1");
argMap.put("arg2", 2);
argMap.put("arg3", "value3");
final String result = new NamedParameterJdbcTemplate(dataSource)
        .queryForObject(query, argMap, String.class);

使用JdbcTemplate的调用过程:

final String query = "call MY_PROCEDURE(?, ?, ?)";
final Object[] args = {"arg1", "arg2", "arg3"};
new JdbcTemplate(dataSource).execute(query, args, String.class);

使用SimpleJdbcCall调用函数:

final String result = new SimpleJdbcCall(dataSource)
        .withCatalogName("MY_PACKAGE")
        .withFunctionName("MY_FUNCTION")
        .executeFunction(String.class, "arg1", "arg2");

使用SimpleJdbcCall的调用过程:

new SimpleJdbcCall(dataSource)
        .withCatalogName("MY_PACKAGE")
        .withProcedureName("MY_PROCEDURE")
        .execute("arg1", arg2);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 2017-06-26
    • 2014-03-24
    • 1970-01-01
    • 2018-03-05
    相关资源
    最近更新 更多