文档首页
MySQL Connector/J 开发人员指南
相关文档 下载本手册
PDF (US Ltr) - 1.2Mb
PDF (A4) - 1.2Mb


MySQL Connector/J 开发人员指南  /  JDBC 概念  /  使用 JDBC CallableStatements 执行存储过程

7.3 使用 JDBC CallableStatements 执行存储过程

Connector/J 完全实现了 java.sql.CallableStatement 接口。

有关 MySQL 存储过程的更多信息,请参阅 使用存储例程

Connector/J 通过 JDBC 的 CallableStatement 接口公开存储过程功能。

以下示例显示了一个存储过程,它将 inOutParam 的值加 1 并返回,并将使用 inputParam 传入的字符串作为 ResultSet 返回。

示例 7.3 Connector/J:调用存储过程

CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), \
                        INOUT inOutParam INT)
BEGIN
    DECLARE z INT;
    SET z = inOutParam + 1;
    SET inOutParam = z;

    SELECT inputParam;

    SELECT CONCAT('zyxw', inputParam);
END


要使用 Connector/J 中的 demoSp 过程,请执行以下步骤:

  1. 使用 Connection.prepareCall() 准备可调用语句。

    请注意,您必须使用 JDBC 转义语法,并且围绕参数占位符的括号不是可选的。

    示例 7.4 Connector/J:使用 Connection.prepareCall()

    import java.sql.CallableStatement;
    
    ...
    
        //
        // Prepare a call to the stored procedure 'demoSp'
        // with two parameters
        //
        // Notice the use of JDBC-escape syntax ({call ...})
        //
    
        CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");
    
    
    
        cStmt.setString(1, "abcdefg");

    注意

    Connection.prepareCall() 是一种昂贵的操作,因为驱动程序执行元数据检索以支持输出参数。出于性能原因,请通过在代码中重用 CallableStatement 实例来尽量减少对 Connection.prepareCall() 的不必要调用。

  2. 注册输出参数(如果有)。

    要检索输出参数的值(在创建存储过程时指定为 OUTINOUT 的参数),JDBC 要求在语句执行之前使用 CallableStatement 接口中的各种 registerOutputParameter() 方法指定它们。

    示例 7.5 Connector/J:注册输出参数

    import java.sql.Types;
    ...
    //
    // Connector/J supports both named and indexed
    // output parameters. You can register output
    // parameters using either method, as well
    // as retrieve output parameters using either
    // method, regardless of what method was
    // used to register them.
    //
    // The following examples show how to use
    // the various methods of registering
    // output parameters (you should of course
    // use only one registration per parameter).
    //
    
    //
    // Registers the second parameter as output, and
    // uses the type 'INTEGER' for values returned from
    // getObject()
    //
    
    cStmt.registerOutParameter(2, Types.INTEGER);
    
    //
    // Registers the named parameter 'inOutParam', and
    // uses the type 'INTEGER' for values returned from
    // getObject()
    //
    
    cStmt.registerOutParameter("inOutParam", Types.INTEGER);
    ...


  3. 设置输入参数(如果有)。

    输入参数和输入/输出参数的设置方式与 PreparedStatement 对象相同。但是,CallableStatement 还支持按名称设置参数。

    示例 7.6 Connector/J:设置 CallableStatement 输入参数

    ...
    
        //
        // Set a parameter by index
        //
    
        cStmt.setString(1, "abcdefg");
    
        //
        // Alternatively, set a parameter using
        // the parameter name
        //
    
        cStmt.setString("inputParam", "abcdefg");
    
        //
        // Set the 'in/out' parameter using an index
        //
    
        cStmt.setInt(2, 1);
    
        //
        // Alternatively, set the 'in/out' parameter
        // by name
        //
    
        cStmt.setInt("inOutParam", 1);
    
    ...


  4. 执行 CallableStatement,并检索任何结果集或输出参数。

    虽然 CallableStatement 支持调用任何 Statement 执行方法(executeUpdate()executeQuery()execute()),但最灵活的调用方法是 execute(),因为您不需要提前知道存储过程是否返回结果集。

    示例 7.7 Connector/J:检索结果和输出参数值

    ...
    
        boolean hadResults = cStmt.execute();
    
        //
        // Process all returned result sets
        //
    
        while (hadResults) {
            ResultSet rs = cStmt.getResultSet();
    
            // process result set
            ...
    
            hadResults = cStmt.getMoreResults();
        }
    
        //
        // Retrieve output parameters
        //
        // Connector/J supports both index-based and
        // name-based retrieval
        //
    
        int outputValue = cStmt.getInt(2); // index-based
    
        outputValue = cStmt.getInt("inOutParam"); // name-based
    
    ...