JDBC批处理与性能

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

使用JDBC进行批处理•java•数据库l业务场景:当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率。l实现批处理有两种方式,第一种方式:•Statement.addBatch(sql)l执行批处理SQL语句•executeBatch()方法:执行批处理命令•clearBatch()方法:清除批处理命令Connectionconn=null;Statementst=null;ResultSetrs=null;try{conn=JdbcUtil.getConnection();Stringsql1=insertintouser(name,password,email,birthday)values('kkk','123','abc@sina.com','1978-08-08');Stringsql2=updateusersetpassword='123456'whereid=3;st=conn.createStatement();st.addBatch(sql1);//把SQL语句加入到批命令中st.addBatch(sql2);//把SQL语句加入到批命令中st.executeBatch();}finally{JdbcUtil.free(conn,st,rs);}l采用Statement.addBatch(sql)方式实现批处理:•优点:可以向数据库发送多条不同的SQL语句。•缺点:•SQL语句没有预编译。•当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。例如:Insertintouser(name,password)values(‘aa’,’111’);Insertintouser(name,password)values(‘bb’,’222’);Insertintouser(name,password)values(‘cc’,’333’);Insertintouser(name,password)values(‘dd’,’444’);l实现批处理的第二种方式:•PreparedStatement.addBatch()conn=JdbcUtil.getConnection();Stringsql=insertintouser(name,password,email,birthday)values(?,?,?,?);st=conn.prepareStatement(sql);for(inti=0;i50000;i++){st.setString(1,aaa+i);st.setString(2,123+i);st.setString(3,aaa+i+@sina.com);st.setDate(4,newDate(1980,10,10));st.addBatch();if(i%1000==0){st.executeBatch();st.clearBatch();}}st.executeBatch();l采用PreparedStatement.addBatch()实现批处理•优点:发送的是预编译后的SQL语句,执行效率高。•缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。JDBC的批处理操作三种方式SQL批处理是JDBC性能优化的重要武器,批处理的用法有三种形式。packagelavasoft.jdbctest;importlavasoft.common.DBToolkit;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.SQLException;importjava.sql.Statement;/***JDBC的批量操作三种方式**@authorleizhimin2009-12-414:42:11*/publicclassBatchExeSQLTest{publicstaticvoidmain(String[]args){exeBatchStaticSQL();}/***批量执行预定义模式的SQL*/publicstaticvoidexeBatchParparedSQL(){Connectionconn=null;try{conn=DBToolkit.getConnection();Stringsql=insertintotestdb.book(kind,name)values(?,?);PreparedStatementpstmt=conn.prepareStatement(sql);pstmt.setString(1,java);pstmt.setString(2,jjjj);pstmt.addBatch();//添加一次预定义参数pstmt.setString(1,ccc);pstmt.setString(2,dddd);pstmt.addBatch();//再添加一次预定义参数//批量执行预定义SQLpstmt.executeBatch();}catch(SQLExceptione){e.printStackTrace();}finally{DBToolkit.closeConnection(conn);}}/***批量执行混合模式的SQL、有预定义的,还有静态的*/publicstaticvoidexeBatchMixedSQL(){Connectionconn=null;try{conn=DBToolkit.getConnection();Stringsql=insertintotestdb.book(kind,name)values(?,?);PreparedStatementpstmt=conn.prepareStatement(sql);pstmt.setString(1,java);pstmt.setString(2,jjjj);pstmt.addBatch();//添加一次预定义参数pstmt.setString(1,ccc);pstmt.setString(2,dddd);pstmt.addBatch();//再添加一次预定义参数//添加一次静态SQLpstmt.addBatch(updatetestdb.booksetkind='JAVA'wherekind='java');//批量执行预定义SQLpstmt.executeBatch();}catch(SQLExceptione){e.printStackTrace();}finally{DBToolkit.closeConnection(conn);}}/***执行批量静态的SQL*/publicstaticvoidexeBatchStaticSQL(){Connectionconn=null;try{conn=DBToolkit.getConnection();Statementstmt=conn.createStatement();//连续添加多条静态SQLstmt.addBatch(insertintotestdb.book(kind,name)values('java','javainaciton'));stmt.addBatch(insertintotestdb.book(kind,name)values('c','cinaciton'));stmt.addBatch(deletefromtestdb.bookwherekind='C#');stmt.addBatch(updatetestdb.booksetkind='JAVA'wherekind='java');//stmt.addBatch(selectcount(*)fromtestdb.book);//批量执行不支持Select语句//执行批量执行stmt.executeBatch();}catch(SQLExceptione){e.printStackTrace();}finally{DBToolkit.closeConnection(conn);}}}注意:JDBC的批处理不能加入select语句,否则会抛异常:java.sql.BatchUpdateException:CannotissueSELECTviaexecuteUpdate().atcom.mysql.jdbc.StatementImpl.executeBatch(StatementImpl.java:1007)深入理解Statement和PreparedStatement一、使用Statement而不是PreparedStatement对象JDBC驱动的最佳化是基于使用的是什么功能.选择PreparedStatement还是Statement取决于你要怎么使用它们.对于只执行一次的SQL语句选择Statement是最好的.相反,如果SQL语句被多次执行选用PreparedStatement是最好的.PreparedStatement的第一次执行消耗是很高的.它的性能体现在后面的重复执行.例如,假设我使用EmployeeID,使用prepared的方式来执行一个针对Employee表的查询.JDBC驱动会发送一个网络请求到数据解析和优化这个查询.而执行时会产生另一个网络请求.在JDBC驱动中,减少网络通讯是最终的目的.如果我的程序在运行期间只需要一次请求,那么就使用Statement.对于Statement,同一个查询只会产生一次网络到数据库的通讯.对于使用PreparedStatement池的情况下,本指导原则有点复杂.当使用PreparedStatement池时,如果一个查询很特殊,并且不太会再次执行到,那么可以使用Statement.如果一个查询很少会被执行,但连接池中的Statement池可能被再次执行,那么请使用PreparedStatement.在不是Statement池的同样情况下,请使用Statement.二、使用PreparedStatement的Batch功能Update大量的数据时,先Prepare一个INSERT语句再多次的执行,会导致很多次的网络连接.要减少JDBC的调用次数改善性能,你可以使用PreparedStatement的AddBatch()方法一次性发送多个查询给数据库.例如,让我们来比较一下下面的例子.例1:多次执行PreparedStatementPreparedStatementps=conn.prepareStatement(INSERTintoemployeesvalues(?,?,?));for(n=0;n100;n++){ps.setString(name[n]);ps.setLong(id[n]);ps.setInt(salary[n]);ps.executeUpdate();}例2:使用BatchPreparedStatementps=conn.prepareStatement(INSERTintoemployeesvalues(?,?,?));for(n=0;n100;n++){ps.setString(name[n]);ps.setLong(id[n]);ps.setInt(salary[n]);ps.addBatch();}ps.executeBatch();在例1中,PreparedStatement被用来多次执行INSERT语句.在这里,执行了100次INSERT操作,共有101次网络往返.其中,1次往返是预储statement,另外100次往返执行每个迭代.在例2中,当在100次INSERT操作中使用addBatch()方法时,只有两次网络往返.1次往返是预储statement,另一次是执行batch命令.虽然Batch命令会用到更多的数据库的CPU周期,但是通过减少网络往返,性能得到提高.记住,JDBC的性能最大的增进是减少JDBC驱动与数据库之间

1 / 10
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功