xiaoan6688 发表于 2013-1-29 14:31:50

PreparedStatement方法详解

PreparedStatement实例包含已编译的SQL语句。这就是使语句“准备好”。包含于PreparedStatement 对象中的SQL语句可具有一个或多个IN参数。IN参数的值在SQL语句创建时未被指定。相反的,该语句为每个IN参数保留一个问号(“?”)作为占位符。每个问号的值必须在该语句执行之前,通过适当的setXXX方法来提供。
由于PreparedStatement对象已预编译过,所以其执行速度要快于Statement对象。因此,多次执行的SQL语句经常创建为PreparedStatement对象,以提高效率。
作为Statement 的 子类,PreparedStatement继承了Statement的所有功能。另外它还添加了一整套方法,用于设置发送给数据库以取代IN参数占位符的 值。同时,三种方法execute、executeQuery和executeUpdate已被更改以使之不再需要参数。这些方法的Statement形 式(接受SQL语句参数的形式)不应该用于PreparedStatement对象。
1、创建PreparedStatement对象
以下的代码段(其中con是Connection对象)创建包含带两个IN参数占位符的SQL语句的PreparedStatement对象:
PreparedStatementpstmt=con.prepareStatement("UPDATEtable4SETm=?WHEREx=?");
pstmt对象包含语句"UPDATEtable4SETm=?WHEREx=?",它已发送给DBMS,并为执行作好了准备。
2、传递IN参数
在 执行PreparedStatement对象之前,必须设置每个?参数的值。这可通过调用setXXX方法来完成,其中XXX是与该参数相应的类型。例 如,如果参数具有Java类型long,则使用的方法就是setLong。setXXX方法的第一个参数是要设置的参数的序数位置,第二个参数是设置给该 参数的值。例如,以下代码将第一个参数设为123456789,第二个参数设为100000000:
pstmt.setLong(1,123456789);
pstmt.setLong(2,100000000);
一旦设置了给定语句的参数值,就可用它多次执行该语句,直到调用clearParameters 方法清除它为止。在连接的缺省模式下(启用自动提交),当语句完成时将自动提交或还原该语句。
如果基本数据库和驱动程序在语句提交之后仍保持这些语句的打开状态,则同一个PreparedStatement可执行多次。如果这一点不成立,那么试图通过使用PreparedStatement 对象代替Statement对象来提高性能是没有意义的。
利 用pstmt(前面创建的PreparedStatement对象),以下代码例示了如何设置两个参数占位符的值并执行pstmt10次。如上所述,为做 到这一点,数据库不能关闭pstmt。在该示例中,第一个参数被设置为"Hi"并保持为常数。在for循环中,每次都将第二个参数设置为不同的值:从0开 始,到9结束。
pstmt.setString(1,"Hi");
for(inti=0;i<10;i++){
pstmt.setInt(2,i);
introwCount=pstmt.executeUpdate();
}
3、IN参数中数据类型的一致性
setXXX 方法中的XXX是Java类型。它是一种隐含的JDBC类型(一般SQL类型),因为驱动程序将把Java类型映射为相应的JDBC类型(遵循该 JDBCGuide中§8.6.2“映射Java和JDBC类型”表中所指定的映射),并将该JDBC类型发送给数据库。例如,以下代码段将 PreparedStatement对象pstmt的第二个参数设置为44,Java类型为short:
pstmt.setShort(2,44);
驱动程序将44作为JDBCSMALLINT发送给数据库,它是Javashort类型的标准映射。
程序员的责任是确保将每个IN参数的Java类型映射为与数据库所需的JDBC数据类型兼容的JDBC类型。不妨考虑数据库需要JDBCSMALLINT 的情况。如果使用方法setByte,则驱动程序将JDBCTINYINT发送给数据库。这是可行的,因为许多数据库可从一种相关的类型转换为另一种类型,并且通常TINYINT可用于SMALLINT适用的任何地方
PreparedStatement相关知识
jdbc(javadatabaseconnectivity,java 数据库连接)的api中的主要的四个类之一的java.sql.statement要求开发者付出大量的时间和精力。在使用statement获取 jdbc访问时所具有的一个共通的问题是输入适当格式的日期和时间戳:2002-02-0520:56或者02/05/028:56pm。
通过使用java.sql.preparedstatement,这个问题可以自动解决。一个preparedstatement是从java.sql.connection 对象和所提供的sql字符串得到的,sql字符串中包含问号(?),这些问号标明变量的位置,然后提供变量的值,最后执行语句,例如:
stringsql="select*frompeoplepwherep.id=?andp.name=?";
preparedstatementps=connection.preparestatement(sql);
ps.setint(1,id);
ps.setstring(2,name);
resultsetrs=ps.executequery();
使用preparedstatement的另一个优点是字符串不是动态创建的。下面是一个动态创建字符串的例子:
stringsql="select*frompeoplepwherep.i="+id;
这允许jvm(javavirtualmachine,java虚拟机)和驱动/数据库缓存语句和字符串并提高性能。preparedstatement 也提供数据库无关性。当显示声明的sql越少,那么潜在的sql语句的数据库依赖性就越小。由于preparedstatement具备很多优点,开发者可能通常都使用它,只有在完全是因为性能原因或者是在一行sql语句中没有变量的时候才使用通常的statement。一个完整的preparedstatement的例子:
packagejstarproject;importjava.sql.*;publicclassmypreparedstatement{privatefinalstringdb_driver="com.microsoft.jdbc.sqlserver.sqlserverdriver";privatefinalstringurl="jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=pubs";publicmypreparedstatement(){}publicvoidquery()throwssqlexception{connectionconn=this.getconnection();stringstrsql="selectemp_idfromemployeewhereemp_id=?";preparedstatementpstmt=conn.preparestatement(strsql);pstmt.setstring(1,"pma42628m");resultsetrs=pstmt.executequery();while(rs.next()){stringfname=rs.getstring("emp_id");system.out.println("thefnameis"+fname);}rs.close();pstmt.close();conn.close();}privateconnectiongetconnection()throwssqlexception{//class.connectionconn=null;try{class.forname(db_driver);conn=drivermanager.getconnection(url,"sa","sa");}catch(classnotfoundexceptionex){}returnconn;}//mainpublicstaticvoidmain(string[]args)throwssqlexception{mypreparedstatementjdbctest1=newmypreparedstatement();jdbctest1.query();}} 
页: [1]
查看完整版本: PreparedStatement方法详解