【问题标题】:Calling Firebird Stored procedure from Java Servlet从 Java Servlet 调用 Firebird 存储过程
【发布时间】:2018-03-24 20:16:35
【问题描述】:

我有一个带有一些存储过程的 Firebird 数据库,我正在开发一个 Java Web/数据库应用程序。我想知道是否有可能以及如何从 java 类或 Servlet 调用这些存储过程。

示例:

  1. 存储过程deletep,用于从数据库中删除一行
  2. 我的 webapp Jsp/servlets
  3. 我想创建一个链接来执行我的删除存储过程

【问题讨论】:

    标签: java stored-procedures jdbc firebird jaybird


    【解决方案1】:

    要在 Java 中执行 Firebird 存储过程,有几种方法。 JDBC-default 方法类似于:

    try (CallableStatement cstmt = connection.prepareStatement(
            "{call yourProcedure(?, ?, ?)}")) {
        cstmt.setString(1, "value1");
        cstmt.setString(2, "value2");
        cstmt.setString(3, "value3");
        cstmt.execute();
    }
    

    如果 Firebird 存储过程是可选的(即:包含 SUSPEND 并且可以返回多行),您需要执行以下操作:

    try (CallableStatement cstmt = connection.prepareStatement(
            "{call yourProcedure(?, ?, ?)}")) {
        cstmt.setString(1, "value1");
        cstmt.setString(2, "value2");
        cstmt.setString(3, "value3");
        try (ResultSet rs = cstmt.executeQuery()) {
            while(rs.next()) {
                // do something with result set rows ...
            }
        }
    }
    

    如果存储过程是可执行的并且不返回任何值,这就足够了。如果存储过程可以通过(多个)返回列执行,您需要类似:

    try (CallableStatement cstmt = connection.prepareStatement(
            "{call yourProcedure(?, ?, ?, ?, ?)}")) {
        cstmt.setString(1, "value1");
        cstmt.setString(2, "value2");
        cstmt.setString(3, "value3");
        cstmt.registerOutParameter(4, Types.VARCHAR);
        cstmt.registerOutParameter(5, Types.VARCHAR)
        cstmt.execute();
    
        String out1 = cstmt.getString(4);
        String out2 = cstmt.getString(5);
        // do something with result
    }
    

    或者,您可以将 Firebird 特定语法 EXECUTE PROCEDURE yourProcedure(?, ?, ?) 用于可执行存储过程和 SELECT * FROM yourProcedure(?, ?, ?)

    【讨论】:

      【解决方案2】:

      这可以使用 Jaybird,Firebird JDBC 驱动程序。

      三个步骤:

      1. 创建一个 DBUtil java 类来存储查询:

        public static void deletePlan(Connection conn, CallableStatement 
                statement, String code, String rev, String mention) throws SQLException {  
        
            statement.setString(1, code);
            statement.setString(2, rev);
            statement.setString(3, mention);
            statement.execute();
        }
        
      2. 创建删除 servlet

        protected void doGet(HttpServletRequest request, 
                HttpServletResponse response) throws ServletException, IOException {
            Connection conn = MyUtils.getStoredConnection(request);
        
            String code = request.getParameter("code");
            String rev = request.getParameter("revision");
            String mention = request.getParameter("mention");
            CallableStatement statement = null;
            try {
                statement = conn.prepareCall("execute procedure 
            DELETEP(?,?,?)");
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        
            String errorString = null;
        
            try {
                DBUtils.deletePlan(conn, statement, code, rev, mention);
            } catch (SQLException e) {
                e.printStackTrace();
                errorString = e.getMessage();
            } 
            .........
        
      3. 在jsp文件中创建删除链接

        <a href="${pageContext.request.contextPath}/deletePlan code=${plan.code}&revision=${plan.revision}&mention=${plan.mention}">Delete</a>
        

      【讨论】:

      • 就我个人而言,我不会创建 DBUtile 类,它是一个奇怪的抽象。阅读 DAO,并将所有与数据库相关的代码移出 servlet。我还建议在步骤 2 中将 try-catch 块合并为一个块,如果第一个块失败,则不应(也不能)执行第二个块。还阅读了 try-with-resources。使用GET 进行删除很奇怪,并且可能不安全(您所需要的只是搜索引擎抓取您的页面或浏览器预取链接以便删除)。你真的应该使用 POST 来删除。
      猜你喜欢
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      • 2017-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多