JDBC - Statements, PreparedStatement 和 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 对象,您就可以使用它通过它的三种执行方法之一来执行一条 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 - 示例代码。