JDBC - Statements, PreparedStatement 和 CallableStatement

一旦获得连接,我们就可以与数据库进行交互。 JDBC Statement、CallableStatementPreparedStatement 接口定义了使您能够发送 SQL 或 PL/SQL 命令并从数据库接收数据的方法和属性。

它们还定义了有助于弥合数据库中使用的 Java 和 SQL 数据类型之间的数据类型差异的方法。

下表提供了每个接口用于决定要使用的接口的目的摘要。

接口 推荐使用
Statement 将其用于对数据库的通用访问。 在运行时使用静态 SQL 语句时很有用。 Statement 接口不能接受参数。
PreparedStatement 当您计划多次使用 SQL 语句时使用它。 PreparedStatement 接口在运行时接受输入参数。
CallableStatement 当您想要访问数据库存储过程时使用它。 CallableStatement 接口还可以接受运行时输入参数。

语句对象

创建语句对象

在您可以使用 Statement 对象执行 SQL 语句之前,您需要使用 Connection 对象的 createStatement( ) 方法创建一个,如下例所示 −

Statement stmt = null;
try {
   stmt = conn.createStatement( );
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

一旦您创建了一个 Statement 对象,您就可以使用它通过它的三种执行方法之一来执行一条 SQL 语句。

  • boolean execute (String SQL): 如果可以检索 ResultSet 对象,则返回布尔值 true; 否则,它返回 false。 使用此方法执行 SQL DDL 语句或需要使用真正动态的 SQL。

  • int executeUpdate (String SQL) − 返回受 SQL 语句执行影响的行数。 使用此方法来执行您希望影响的行数的 SQL 语句 - 例如,INSERT、UPDATE 或 DELETE 语句。

  • ResultSet executeQuery (String SQL) − 返回一个 ResultSet 对象。 当您希望获得结果集时使用此方法,就像使用 SELECT 语句一样。


关闭语句对象

正如您关闭 Connection 对象以节省数据库资源一样,出于同样的原因,您也应该关闭 Statement 对象。

对 close() 方法的简单调用就可以完成这项工作。 如果先关闭 Connection 对象,它也会关闭 Statement 对象。 但是,您应该始终显式关闭 Statement 对象以确保正确清理。

Statement stmt = null;
try {
   stmt = conn.createStatement( );
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   stmt.close();
}

为了更好地理解,我们建议您学习语句 - 示例教程


PreparedStatement 对象

PreparedStatement 接口扩展了 Statement 接口,它为您提供了与通用 Statement 对象相比具有几个优点的附加功能。

此语句为您提供动态提供参数的灵活性。


创建 PreparedStatement 对象

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

JDBC 中的所有参数都由 ? 符号表示,该符号称为参数标记。 在执行 SQL 语句之前,您必须为每个参数提供值。

setXXX() 方法将值绑定到参数,其中 XXX 表示您希望绑定到输入参数的值的 Java 数据类型。 如果您忘记提供这些值,您将收到 SQLException。

每个参数标记由其序号位置引用。 第一个标记代表位置 1,下一个位置代表 2,依此类推。 此方法不同于 Java 数组索引,后者从 0 开始。

Statement 对象的 与数据库交互的所有方法 (a) execute()、(b) executeQuery() 和 (c) executeUpdate() 也适用于 PreparedStatement 对象。 但是,这些方法被修改为使用可以输入参数的 SQL 语句。


关闭 PreparedStatement 对象

就像关闭 Statement 对象一样,出于同样的原因,您也应该关闭 PreparedStatement 对象。

对 close() 方法的简单调用就可以完成这项工作。 如果先关闭 Connection 对象,它也会关闭 PreparedStatement 对象。 但是,您应该始终显式关闭 PreparedStatement 对象以确保正确清理。

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   pstmt.close();
}

为了更好地理解,让我们学习Prepare - 示例代码


CallableStatement 对象

正如 Connection 对象创建 Statement 和 PreparedStatement 对象一样,它还创建 CallableStatement 对象,该对象将用于执行对数据库存储过程的调用。


创建 CallableStatement 对象

假设,您需要执行以下 Oracle 存储过程 −

CREATE OR REPLACE PROCEDURE getEmpName 
   (EMP_ID IN NUMBER, EMP_FIRST OUT VARCHAR) AS
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END;

注意 − 上面的存储过程是为 Oracle 编写的,但是我们正在使用 MySQL 数据库,所以,让我们为 MySQL 编写相同的存储过程,如下所示在 EMP 数据库中创建它 −

DELIMITER $$

DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
CREATE PROCEDURE `EMP`.`getEmpName` 
   (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
BEGIN
   SELECT first INTO EMP_FIRST
   FROM Employees
   WHERE ID = EMP_ID;
END $$

DELIMITER ;

存在三种类型的参数:IN、OUT 和 INOUT。 PreparedStatement 对象仅使用 IN 参数。 CallableStatement 对象可以使用所有这三个。

以下是每个的定义 −

参数 描述
IN 创建 SQL 语句时其值未知的参数。 您可以使用 setXXX() 方法将值绑定到 IN 参数。
OUT 一个参数,其值由它返回的 SQL 语句提供。 您可以使用 getXXX() 方法从 OUT 参数中检索值。
INOUT 提供输入和输出值的参数。 您使用 setXXX() 方法绑定变量并使用 getXXX() 方法检索值。

下面的代码片段展示了如何使用 Connection.prepareCall() 方法基于前面的存储过程实例化一个 CallableStatement 对象 −

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

String 变量 SQL,表示带有参数占位符的存储过程。

使用 CallableStatement 对象与使用 PreparedStatement 对象非常相似。 在执行语句之前,您必须将值绑定到所有参数,否则您将收到 SQLException。

如果您有 IN 参数,只需遵循适用于 PreparedStatement 对象的相同规则和技术; 使用与您要绑定的 Java 数据类型相对应的 setXXX() 方法。

当您使用 OUT 和 INOUT 参数时,您必须使用额外的 CallableStatement 方法 registerOutParameter()。 registerOutParameter() 方法将 JDBC 数据类型绑定到存储过程预期返回的数据类型。

调用存储过程后,您可以使用适当的 getXXX() 方法从 OUT 参数中检索值。 此方法将检索到的 SQL 类型值转换为 Java 数据类型。


关闭 CallableStatement 对象

就像关闭其他 Statement 对象一样,出于同样的原因,您也应该关闭 CallableStatement 对象。

对 close() 方法的简单调用就可以完成这项工作。 如果先关闭 Connection 对象,它也会关闭 CallableStatement 对象。 但是,您应该始终显式关闭 CallableStatement 对象以确保正确清理。

CallableStatement cstmt = null;
try {
   String SQL = "{call getEmpName (?, ?)}";
   cstmt = conn.prepareCall (SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   cstmt.close();
}

为了更好地理解,建议研究 Callable - 示例代码