JDBC Statement,PreparedStatement和CallableStatement

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

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

下表总结了每个接口的用途,以决定要使用的接口。

接口
推荐使用
Statement

将其用于对数据库的通用访问。在运行时使用静态SQL语句时非常有用。Statement接口不能接受参数。

PreparedStatement

当您计划多次使用SQL语句时,请使用此选项。PreparedStatement接口在运行时接受输入参数。

CallableStatement

当您要访问数据库存储过程时,请使用此选项。CallableStatement接口还可以接受运行时输入参数。

Statement 对象

创建 Statement 对象

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

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

一旦创建了Statement对象,就可以使用其三个执行方法之一来执行SQL语句。

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

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

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

关闭Statement 对象

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

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

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

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

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();
}

为了更好地理解,让我们学习“PreparedStatement 示例代码”

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;

NOTE: 上面的存储过程已经为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 something。

OUT

其值由返回的SQL语句提供的参数。使用getXXX()方法从参数中检索值。

INOUT

同时提供输入和输出值的参数。可以使用 setXXX ()方法绑定变量,并使用 getXXX ()方法检索值。

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

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

字符串变量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();
}

为了更好地理解,我建议学习CallableStatement 示例代码