获得连接后,我们可以与数据库进行交互. JDBC 语句,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 接口扩展了Statement接口,它为您提供了一些优于通用Statement对象的功能.
此语句为您提供了动态提供参数的灵活性.
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语句.
正如关闭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(); }
就像Connection对象创建Statement和PreparedStatement对象一样还会创建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数据类型绑定到存储过程应返回的数据类型.
调用存储过程后,从OUT参数中检索值使用适当的getXXX()方法.此方法将检索到的SQL类型的值转换为Java数据类型.
就像关闭其他Statement对象一样,同样的原因你也应该关闭CallableStatement对象.
对close()方法的简单调用将完成这项工作.如果先关闭Connection对象,它也将关闭CallableStatement对象.但是,您应该始终显式关闭CallableStatement对象以确保正确清理.
CallableStatement cstmt = null; try { String SQL = "{call getEmpName (?, ?)}"; cstmt = conn.prepareCall (SQL); . . . } catch (SQLException e) { . . . } finally { cstmt.close(); }