JDBC - Statement、PreparedStatement和CallableStatement



获得连接后,我们可以与数据库交互。JDBC 的Statement、CallableStatementPreparedStatement接口定义了用于发送SQL或PL/SQL命令以及从数据库接收数据的方法和属性。

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

下表总结了每个接口的目的,以帮助您决定使用哪个接口。

接口 推荐用途
Statement 用于对数据库进行通用访问。在运行时使用静态SQL语句时非常有用。Statement接口不能接受参数。
PreparedStatement 当您计划多次使用SQL语句时使用。PreparedStatement接口在运行时接受输入参数。
CallableStatement 当您要访问数据库存储过程时使用。CallableStatement接口也可以接受运行时输入参数。

Statement 对象

创建 Statement 对象

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

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

创建Statement对象后,您可以使用其三个execute方法之一来执行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语句时)使用此方法。

关闭 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数组索引不同,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 {
   . . .
}

字符串变量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 - 示例代码

广告
© . All rights reserved.