预编译的 SQL 语句的对象-PreparedStatement

来源:互联网 发布:织梦v57漏洞 编辑:程序博客网 时间:2024/06/05 20:25

           有人主张,在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement。为什么呢?一.代码的可读性和可维护性.二、PreparedStatement的效率比较高,数据库语句可以复用。三、安全性高,防注入。

          PreparedStatement 实例包含已编译的 SQL语句。这就是使语句准备好。包含于PreparedStatement对象中的 SQL语句可具有一个或多个 IN参数。IN参数的值在 SQL语句创建时未被指定。相反的,该语句为每个 IN参数保留一个问号()作为占位符。每个问号的值必须在该语句执行之前,通过适当的setXXX方法来提供。

         由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象。因此,多次执行的 SQL语句经常创建为 PreparedStatement对象,以提高效率。

         作为 Statement 的子类,PreparedStatement继承了 Statement的所有功能。另外它还添加了一整套方法,用于设置发送给数据库以取代 IN 参数占位符的值。同时,三种方法 execute executeQuery executeUpdate已被更改以使之不再需要参数。这些方法的 Statement形式(接受 SQL语句参数的形式)不应该用于 PreparedStatement对象。

-创建 PreparedStatement对象

         以下的代码段(其中 con Connection对象)创建包含带两个 IN参数占位符的 SQL语句的 PreparedStatement对象:

         PreparedStatementpstmt = con.prepareStatement("UPDATE table4 SET m = ? WHERE x = ?");

         pstmt 对象包含语句 "UPDATE table4 SET m = ? WHERE x = ?",它已发送给DBMS,并为执行作好了准备。

 

-传递 IN参数

         在执行 PreparedStatement 对象之前,必须设置每个 ?参数的值。这可通过调用 setXXX方法来完成,其中 XXX是与该参数相应的类型。例如,如果参数具有Java类型 long,则使用的方法就是 setLongsetXXX方法的第一个参数是要设置的参数的序数位置,第二个参数是设置给该参数的值。例如,以下代码将第一个参数设为 123456789,第二个参数设为 100000000

         pstmt.setLong(1, 123456789);pstmt.setLong(2, 100000000);

         一旦设置了给定语句的参数值,就可用它多次执行该语句,直到调用clearParameters方法清除它为止。在连接的缺省模式下(启用自动提交),当语句完成时将自动提交或还原该语句。 

         如果基本数据库驱动程序在语句提交之后仍保持这些语句的打开状态,则同一个 PreparedStatement 可执行多次。如果这一点不成立,那么试图通过使用PreparedStatement对象代替 Statement对象来提高性能是没有意义的。 

         利用 pstmt(前面创建的 PreparedStatement对象),以下代码例示了如何设置两个参数占位符的值并执行 pstmt 10 次。如上所述,为做到这一点,数据库不能关闭 pstmt。在该示例中,第一个参数被设置为 "Hi"并保持为常数。在 for循环中,每次都将第二个参数设置为不同的值:从 0开始,到 9结束。

         pstmt.setString(1,"Hi");

         for (int i= 0; i < 10; i++)

          {

          pstmt.setInt(2, i);int rowCount = pstmt.executeUpdate();

          }

          例:



package com.JDBC.TEST;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import com.JDBC.ConnectionFactory.ConnectionFactory;import java.sql.PreparedStatement;public class JDBCPreparedStatement {Connection con = null;PreparedStatement ps = null;ResultSet rs = null;int value = 0;public static void main(String[] args) {// new JDBCPreparedStatement().updateDB();new JDBCPreparedStatement().deleteDB();}   //增加记录public void updateDB() {con = ConnectionFactory.reCon();StringBuffer SQL = new StringBuffer();SQL.append("INSERT INTO TB_JDBC ");SQL.append("(classname) ");SQL.append("VALUE (?)");try {ps = con.prepareStatement(SQL.toString());for (int i = 6; i < 1006; i++) {ps.setString(1, "DS120" + i);value = ps.executeUpdate();}System.out.println("effect rows" + value);} catch (SQLException e) {e.printStackTrace();} finally {ConnectionFactory.colse(ps, con, rs);}}     //删除记录public void deleteDB() {con = ConnectionFactory.reCon();StringBuffer SQL = new StringBuffer();SQL.append("DELETE FROM TB_JDBC ");SQL.append("WHERE classid > ? AND classid < ?");try {ps = con.prepareStatement(SQL.toString());ps.setInt(1, 2);ps.setInt(2, 2003);value = ps.executeUpdate();System.out.println("effect rows" + value);} catch (SQLException e) {e.printStackTrace();}}}