JDBC - Statements, PreparedStatement and CallableStatement
-
简述
一旦获得连接,我们就可以与数据库进行交互。JDBC Statement、CallableStatement和PreparedStatement接口定义了使您能够发送 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 对象,就可以使用它通过三个 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 语句一样。
-
-
结束语对象
正如您关闭 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 object's与数据库交互的方法 (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(); }
-
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 对象可以使用所有三个。以下是每个的定义 -范围 描述 在 创建 SQL 语句时其值未知的参数。您可以使用 setXXX() 方法将值绑定到 IN 参数。 出去 一个参数,其值由它返回的 SQL 语句提供。您可以使用 getXXX() 方法从 OUT 参数中检索值。 进出 提供输入和输出值的参数。您可以使用 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(); }