JDBC CallableStatement接口

时间:2020-01-09 10:35:20  来源:igfitidea点击:

在JDBC API中,有一个Statement接口,该接口提供了执行静态SQL语句的功能。然后是PreparedStatement接口,该接口扩展了Statement,并添加了创建参数化SQL语句的功能。 PreparedStatement由JDBC API中的CallableStatement扩展,它提供了执行SQL存储过程的功能。

如何获取CallableStatement对象

我们可以通过调用Connection接口的prepareCall()方法来获取CallableStatement实例。

CallableStatement callableStatement = connection.prepareCall(“{call PROCEDURE_NAME(?, ?, ?)}”);

此处的"?"是用于注册IN,OUT和INOUT参数的占位符。

如果我们想使用Callable语句来调用函数,

CallableStatement callableStatement = connection.prepareCall(“? = {call PROCEDURE_NAME(?, ?, ?)}”);

CallableStatement中的方法

CallableStatement从其父类继承了execute方法

  • execute()–执行任何SQL语句。该方法返回一个布尔值;如果第一个结果是ResultSet对象,则为true;否则为false。如果是更新计数或者没有结果,则返回false。
  • executeQuery()–执行返回ResultSet的SQL语句。
  • executeUpdate()–执行SQL语句,该语句可以是INSERT,UPDATE或者DELETE之类的DML语句,也可以是不返回任何内容的SQL语句,例如SQL DDL语句(创建,删除)。

有几种设置方法,用于传递适当类型的IN和INOUT参数的值。

  • setDate(String parameterName,Date x)–使用运行应用程序的虚拟机的默认时区,将指定参数设置为给定的java.sql.Date值。
  • setDouble(String parameterName,double x)–将指定参数设置为给定的Java double值。
  • setFloat(String parameterName,float x)–将指定参数设置为给定的Java float值。
  • setInt(String parameterName,int x)–将指定参数设置为给定的Java int值。
  • setLong(String parameterName,long x)-将指定的参数设置为给定的Java long值。
  • setShort(String parameterName,short x)–将指定参数设置为给定的Java short值。
  • setString(String parameterName,String x)–将指定参数设置为给定的Java String值。
  • setTime(String parameterName,Time x)–将指定参数设置为给定的java.sql.Time值。

也有与之对应的getter方法,用于从OUT参数中检索值。

我们需要使用registerOutParameter()方法的重载变体之一注册out参数,我们可以在其中传递参数的索引或者参数名称。

  • registerOutParameter(int parameterIndex,int sqlType)–将OUT参数在顺序位置parameterIndex中注册到JDBC类型sqlType。
  • registerOutParameter(String parameterName,int sqlType)–将名为parameterName的OUT参数注册到JDBC类型sqlType。

CallableStatement Java示例

1.在此CallableStatement示例中,我们将执行同时具有IN和OUT参数的存储过程。在存储过程中,有一个SELECT语句可通过传递其ID来获取有关雇员的数据。有一个用于ID的IN参数和三个用于检索到的数据的OUT参数。

SQL过程

CREATE PROCEDURE `select_employee_by_id`(IN param_id int, 
    OUT param_fname varchar(45), 
    OUT param_lname varchar(45), 
    OUT param_dept varchar(45))
BEGIN
 SELECT first_name, last_name, department 
 INTO param_fname, param_lname, param_dept
 from EMPLOYEE 
 where id = param_id;
END
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.JDBCType;
import java.sql.SQLException;

public class CallableStatementDemo {
  public static void main(String[] args) {
    Connection connection = null;
    try {
      Class.forName("com.mysql.cj.jdbc.Driver");
      connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/theitroad", 
        "root", "admin");
      // CallableStatement object
      CallableStatement callableStatement = connection.prepareCall(
        "{call select_employee_by_id(?, ?, ?, ?)}");
      // Setting IN parameter - employee ID
      callableStatement.setInt(1, 5);
      // Registering OUT parameters
      callableStatement.registerOutParameter(2, JDBCType.VARCHAR);
      callableStatement.registerOutParameter(3, JDBCType.VARCHAR);
      callableStatement.registerOutParameter(4, JDBCType.VARCHAR);
      
      callableStatement.executeQuery();	      	    
      System.out.println("Employee Record " + "First Name: " + callableStatement.getString(2) + 
          " Last Name: " + callableStatement.getString(3) +
          " Department: " + callableStatement.getString(4));
	     
    } catch (ClassNotFoundException | SQLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }finally{
      if(connection != null){         
        try {
          connection.close();
        } catch (SQLException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      } 
    }
  }
}

2.这是另一个CallableStatement Java示例,其中存储过程返回一个ResultSet(多个记录)。

SQL过程

CREATE PROCEDURE `select_all_employee`()
BEGIN
  SELECT * FROM employee;
END
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

public class CallableStatementDemo {
  public static void main(String[] args) {
    Connection connection = null;
    try {
      // Load driver
      Class.forName("com.mysql.cj.jdbc.Driver");
      // connection object
      connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/theitroad", 
        "root", "admin");
      // Getting CallableStatement object
      CallableStatement callableStatement = connection.prepareCall(
        "{call select_all_employee()}");
    
      ResultSet rs = callableStatement.executeQuery();
      while(rs.next()){
        System.out.println("Employee Id: " + rs.getInt("id") + 
            " First Name: " + rs.getString("FIRST_NAME") + 
            " Last Name: " + rs.getString("LAST_NAME") + 
            " Department: " + rs.getString("DEPARTMENT")); 
      }	   	    
    } catch (ClassNotFoundException | SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
      if(connection != null){         
        try {
          connection.close();
        } catch (SQLException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      } 
    }
  }
}