【问题标题】:Create and use a stored procedure with Play Framework and JPA使用 Play Framework 和 JPA 创建和使用存储过程
【发布时间】:2013-02-21 04:17:37
【问题描述】:

我正在使用 Play 框架 1.2.5,我想通过创建存储过程并使用它们来优化我的 SQL 查询,但我不知道该怎么做。

通过Java代码创建存储过程应该怎么做?另外,我是否应该在 @OnApplicationStart 作业中执行此操作,以确保在应用程序启动时创建和存储过程?

之后,我该如何使用我的存储过程?使用哪个功能?如何将参数传递给我的程序?如何检索我的程序的结果? (通常结果将是一个 SELECT 查询)最后,是否可以将我的过程的结果绑定到 play 框架中的模型?

我有很多问题,但我是使用 play framework 和 JPA 的存储过程的新手,我想确保我正确使用它们

感谢您的帮助

【问题讨论】:

    标签: jpa stored-procedures playframework playframework-1.x


    【解决方案1】:

    我不知道你应该如何创建它们。也许 OnApplicationStart 方法是您所需要的。在我的环境中,程序已经到位。我们只是使用 Play 来调用它们。要调用存储过程,您应该查看Work 接口。通过实现这一点,您可以在数据库中执行语句。

    我们创建了一个基本的 OracleProcedure 类:

    public class CallOracleProcedure implements Work {
    
        private String anonymousPLSQL;
        private String[] parameters;
    
        public CallOracleProcedure(String anonymousPLSQL, String[] parameters) {
            this.anonymousPLSQL = anonymousPLSQL;
            this.parameters = parameters.clone();
        }
    
        /**
         * Create a JDBC PreparedStatement and then execute the anonymous
         * PL/SQL procedure.
         */
        @Override
        public void execute(Connection connection) {
            PreparedStatement statement = null;
            try {
                statement = connection.prepareStatement("begin " + anonymousPLSQL + "; end;");
    
                if (parameters != null) {
                    int i = 1;
                    for (String param : parameters) {
                        statement.setString(i++, param);
                    }
                }
                statement.executeUpdate();
            } catch (SQLException e) {
                Logger.error("Error performing anonymous pl/sql statement: '%s', with parameters: '%s' - catched error '%s'", anonymousPLSQL, parameters, e);
            } finally {
                if (statement != null) {
                    try {
                        statement.close();
                    } catch (Exception e) {
                        Logger.error("Error closing statement: %s", e);
                    }
                }
            }
        }
    }
    

    对于每个特定的存储过程,您可以扩展此类并将名称和参数通过super()传递给构造函数:

    public class StoredProcedureCall extends CallOracleProcedure {
        public StoredProcedureCall(String param) {
            super("package.storedprocedure(?)", new String[] { orgname });
        }
    }
    

    在您的代码中,您可以这样调用它:

    StoredProcedureCall procedure = new StoredProcedureCall("your parameter");
    session.doWork(procedure);
    

    如果您需要调用过程并检索返回值,您可以在execute() 方法中使用CallableStatement

    public class ProcedureWithReturnValue implements Work {
    
        private final String parameter;
        private String returnValue = null;
    
        public ProcedureWithReturnValue (final String parameter) {
            this.parameter = parameter;
        }
    
        @Override
        public void execute(Connection connection) {
            CallableStatement statement = null;
    
            try {   
                statement = connection.prepareCall("begin ? := package.procedure(?); end;");
                statement.registerOutParameter(1, OracleTypes.VARCHAR);
                statement.setString(2, parameter);
                statement.execute();
    
                returnValue = statement.getString(1);
            } catch (SQLException e) {
                Logger.error("Error getting return value - catched error '%s'",  e);
            }
        }
    
        public String getReturnValue() {
            return returnValue;
        }
    }
    

    【讨论】:

    • 谢谢!你知道如何从过程中检索 SELECT 查询的结果吗?
    • 我添加了另一个返回值的示例。我希望这就是你的意思。
    • 感谢您的回答。您的示例是否适用于返回多个结果的 SELECT ?
    • 我想是的,我还没有尝试过。我想你可以注册多个输出参数。
    【解决方案2】:

    查看用于创建存储过程的演变 (http://www.playframework.com/documentation/1.2.7/evolutions)。

    【讨论】:

    • 仅链接的答案根本不是答案。链接过时了。在您的答案中包含内容。
    • 我不会复制/粘贴另一个网站的全部内容,Okuma。我确实认为对 Fabian 来说,提到“进化”就足够了。要实现这一点,您需要多于几行注释。
    猜你喜欢
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多