JDBC中的PreparedStatement相比Statement的好处有哪些?

时间:2020-12-27 11:55:33
1、相对比较安全,可以防止sql注入
2、有预编译功能,相同操作批量数据效率较高


PreparedStatement 是预编译 ,使用Statement时 sql 中要进行很多的单引号拼接字符串,首先是容易出错也比较麻烦,还有就是存在sql 注入问题这是从安全方面说的。 PreparedStatement  传参数时候用 了占位符 “?”很好的解决了以上Statement的问题。我所体会到得的就是这些。 


PreparedStatement是在执行前先输入sql语句,Statement正好相反,是在执行的时候传入sql语句的。
这样的区别在于,PreparedStatement可以在传入sql后,执行语句前,给参数赋值,避免了因普通的拼接sql字符串语句所带来的安全问题,而且准备sql和执行sql是在两个语句里面完成的,也提高了语句执行的效率。
Statement,就没有以前所说的功能了,我一般很少用



JDBC PreparedStatement 批量更新数据注意的问题

JDBClog4j工作     PreparedStatement 批量更新数据可以提升程序执行效率,缩短程序运行时间,但是在实际工作中运用时,发现要注意以下几个问题:

     系统环境:
JDK1.6.0_21
Oracle10g
Eclipse3.6.1

     用到的jar包:
ojdbc6.jar
commons.logging-1.1.1.jar
commons-dbcp-1.4.jar
commons-pool-1.5.5.jar
commons-collections-3.2.1.jar
log4j-1.2.6.jar
spring2.5.6.jar

     (1)虽然是批量提交,但当数据量大时应该将提交设置为每500次已提交(更具具体情况而定),这么干的好处可以节约内存资源,至少不会因为内存不够用而报内存溢出的异常,在有就是可以加快数据库的执行效率。
     (2)connect.commit()后connect可能会被关闭,需要再次开启

事例代码如下:

Java代码  JDBC中的PreparedStatement相比Statement的好处有哪些?
  1. static Logger log = Logger.getLogger(UpdateLog.class);  
  2. static final int COMMIT = 500;          //每500条记录一提交   
  3. Connection connect = null;  
  4. PreparedStatement pstmt = null;  
  5. String strsql = null;  
  6.   
  7. **  
  8.  * 办公用品结款  
  9.  * @param supid  
  10.  * @param rows  
  11.  * @param jg_je  
  12.  * @param s_je  
  13.  * @param cpid  
  14.  */  
  15. public void ULogOffice(int supid,int rows,double jg_je,double s_je,List<CPInfoData> cpid){  
  16.     int rowsTmp = 0;  
  17.     try {  
  18.             connect = DBConn.getConnection(); //打开一个池连接  
  19.             connect.setAutoCommit(false);  
  20.               
  21.             //第一步:更新t_supplier_log 表  
  22.             strsql = "INSERT INTO t_bi_supplier_log VALUES(?,sysdate,?,?,?,0,'首次','办公厨房','SYSTEM','ONE')";  
  23.             insertInfo(supid, rows, jg_je, s_je);  
  24.               
  25.             //第二步:更新syn_provid_psjh_mx 表中 lb1 为 40  
  26.             strsql = "UPDATE syn_provid_psjh_mx SET lb1='40' " +   
  27.                      "WHERE jhdate=? AND sup_id=? AND lb=? AND rkdh=? AND jkdate is null";  
  28.               
  29.             if(cpid.size()!=0){  
  30.                 for (CPInfoData cpInfoData : cpid) {  
  31.                     //门店 用sup_id、jhdate、lb、id确定唯一一条记录  
  32.                     pstmt = connect.prepareStatement(strsql.toString());  
  33.                     pstmt.setDate(1, Date.valueOf(cpInfoData.getJhdate().substring(0,10)));    
  34.                     pstmt.setInt(2, supid);  
  35.                     pstmt.setString(3, cpInfoData.getLb());  
  36.                     pstmt.setString(4, cpInfoData.getDh().trim());  
  37.                     pstmt.addBatch();  
  38.                     if(rowsTmp%COMMIT==0){//每500条记录一提交  
  39.                         pstmt.executeBatch();  
  40.                         connect.commit();  
  41.                         if (null==connect) { //如果连接关闭了 就在创建一个 为什么要这样 原因是 conn.commit()后可能conn被关闭  
  42.                             connect = DBConn.getConnection();   
  43.                             connect.setAutoCommit(false);  
  44.                         }  
  45.                     }  
  46.                     rowsTmp++;  
  47.                 }  
  48.                 pstmt.executeBatch();  
  49.                 connect.commit();  
  50.             }  
  51.             connect.setAutoCommit(true);  
  52.             log.info("ULogOffice 办公用品 [" + supid +"] 数据库更新完毕" );  
  53.         }catch (Exception e) {  
  54.             try {  
  55.                 connect.rollback();  
  56.                 log.info("ULogOffice 办公用品 [" + supid +"] 数据库更新异常-回滚[" + e.getMessage() + "]");  
  57.             } catch (SQLException e1) {  
  58.                 e1.printStackTrace();  
  59.             }  
  60.             e.printStackTrace();  
  61.         }finally{  
  62.             closePstmt(pstmt);  
  63.             closeConnection(connect);  
  64.         }