Statements、PreparedStatement及CallableStatement(三)
当获得了与数据库的连接后,就可以与数据库进行交互了。
JDBC Statement,CallableStatement和PreparedStatement接口定义了可用于发送SQL或PL/SQL命令,并从数据库接收数据的方法和属性。
- Statement:用于对数据库进行通用访问,在运行时使用静态SQL语句时很有用。 Statement接口不能接受参数。
- PreparedStatement:当计划要多次使用SQL语句时使用。PreparedStatement接口在运行时接受输入参数。
- CallableStatement:当想要访问数据库存储过程时使用。CallableStatement接口也可以接受运行时输入参数。
一、 Statement对象
使用Connection对象的createStatement()方法创建一个Statement对象。范例如下:
Statement stmt = null; try { stmt = conn.createStatement( ); . . . } catch (SQLException e) { . . . } finally { //关闭资源 }
Statement常用的方法有:
-
boolean execute (String SQL)
如果可以检索到ResultSet对象,则返回一个布尔值true; 否则返回false。使用此方法执行SQLDDL语句或需要使用真正的动态SQL,可使用于执行创建数据库,创建表的SQL语句等等。 -
int executeUpdate (String SQL)
返回受SQL语句执行影响的行数。 -
ResultSet executeQuery(String SQL)
返回一个ResultSet对象。 当您希望获得结果集时,请使用此方法,就像使用SELECT语句一样。
注:如果先关闭Connection对象,它也会关闭Statement对象。 但是,应该始终显式关闭Statement对象,以确保正确的清理顺序。
二、PreparedStatement
PreparedStatement接口扩展了Statement接口,比Statement更优秀。此语句可以动态地提供/接受参数。
PreparedStatement可以有效防止sql注入,所以生产环境上一定要使用PreparedStatement,而不能使用Statement。因为PrepareStatement对象会把用户非法输入的单引号用\反斜杠做了转义,从而达到了防止sql注入的目的。
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对象与数据库交互的方法:
-
execute()
-
executeQuery()
-
executeUpdate()
三、CallableStatement对象
用于执行对数据库存储过程的调用。
CallableStatement存在三种类型的参数IN,OUT和INOUT。 PreparedStatement对象只使用IN参数。
(1) IN:创建SQL语句时其参数值是未知的。 使用setXXX()方法将值绑定到IN参数。
(2) OUT:由SQL语句返回的参数值。可以使用getXXX()方法从OUT参数中检索值。
(3) INOUT:提供输入和输出值的参数。使用setXXX()方法绑定变量并使用getXXX()方法检索值。
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; MySQL: 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 ; 范例: CallableStatement cstmt = null; try { String strSQL = "{call getEmpName (?, ?)}"; cstmt = conn.prepareCall (SQL); . . . } catch (SQLException e) { . . . } finally { cstmt.close(); } -- String变量strSQL表示存储过程,带有两个参数占位符。