📜  JDBC-语句,PreparedStatement和CallableStatement

📅  最后修改于: 2020-11-13 04:33:23             🧑  作者: Mango


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

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

下表概述了每个接口决定使用的接口的目的。

Interfaces Recommended Use
Statement Use this for general-purpose access to your database. Useful when you are using static SQL statements at runtime. The Statement interface cannot accept parameters.
PreparedStatement Use this when you plan to use the SQL statements many times. The PreparedStatement interface accepts input parameters at runtime.
CallableStatement Use this when you want to access the database stored procedures. The CallableStatement interface can also accept runtime input parameters.

语句对象

创建语句对象

在使用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时,请使用此方法执行SQL DDL语句。

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

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

结帐对象

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

只需调用close()方法即可完成此工作。如果先关闭Connection对象,它也会关闭Statement对象。但是,您应始终显式关闭Statement对象,以确保正确清理。

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

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

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

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

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对象可以使用所有这三个对象。

这是每个的定义-

Parameter Description
IN A parameter whose value is unknown when the SQL statement is created. You bind values to IN parameters with the setXXX() methods.
OUT A parameter whose value is supplied by the SQL statement it returns. You retrieve values from theOUT parameters with the getXXX() methods.
INOUT A parameter that provides both input and output values. You bind variables with the setXXX() methods and retrieve values with the getXXX() methods.

以下代码段显示了如何使用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-Example Code