使用JDBC在MySQL数据库中如何快速批量插入数据
使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(10W+),如何提高效率呢?
在JDBC编程接口中Statement有两个方法特别值得注意:
voidaddBatch()throwsSQLException
AddsasetofparameterstothisPreparedStatementobject'sbatchofcommands.
int[]executeBatch()throwsSQLException
Submitsabatchofcommandstothedatabaseforexecutionandifallcommandsexecutesuccessfully,returnsanarrayofupdatecounts.Theintelementsofthearraythatisreturnedareorderedtocorrespondtothecommandsinthebatch,whichareorderedaccordingtotheorderinwhichtheywereaddedtothebatch.
通过使用addBatch()和executeBatch()这一对方法可以实现批量处理数据。
不过值得注意的是,首先需要在数据库链接中设置手动提交,connection.setAutoCommit(false),然后在执行Statement之后执行connection.commit()。
packagecyl.demo.ipsearcher; importjava.io.BufferedReader; importjava.io.FileInputStream; importjava.io.IOException; importjava.io.InputStreamReader; importjava.sql.Connection; importjava.sql.DriverManager; importjava.sql.PreparedStatement; importjava.sql.SQLException; publicclassDbStoreHelper{ privateStringinsert_sql; privateStringcharset; privatebooleandebug; privateStringconnectStr; privateStringusername; privateStringpassword; publicDbStoreHelper(){ connectStr="jdbc:mysql://localhost:3306/db_ip"; //connectStr+="?useServerPrepStmts=false&rewriteBatchedStatements=true"; insert_sql="INSERTINTOtb_ipinfos(iplong1,iplong2,ipstr1,ipstr2,ipdesc)VALUES(?,?,?,?,?)"; charset="gbk"; debug=true; username="root"; password="***"; } publicvoidstoreToDb(StringsrcFile)throwsIOException{ BufferedReaderbfr=newBufferedReader(newInputStreamReader(newFileInputStream(srcFile),charset)); try{ doStore(bfr); }catch(Exceptione){ e.printStackTrace(); }finally{ bfr.close(); } } privatevoiddoStore(BufferedReaderbfr)throwsClassNotFoundException,SQLException,IOException{ Class.forName("com.mysql.jdbc.Driver"); Connectionconn=DriverManager.getConnection(connectStr,username,password); conn.setAutoCommit(false);//设置手动提交 intcount=0; PreparedStatementpsts=conn.prepareStatement(insert_sql); Stringline=null; while(null!=(line=bfr.readLine())){ String[]infos=line.split(";"); if(infos.length<5)continue; if(debug){ System.out.println(line); } psts.setLong(1,Long.valueOf(infos[0])); psts.setLong(2,Long.valueOf(infos[1])); psts.setString(3,infos[2]); psts.setString(4,infos[3]); psts.setString(5,infos[4]); psts.addBatch();//加入批量处理 count++; } psts.executeBatch();//执行批量处理 conn.commit();//提交 System.out.println("Alldown:"+count); conn.close(); } }
执行完成以后:
Alldown:103498
Convertfinished.
Allspendtime/s:47
一共10W+,执行时间一共花费47秒.
这个效率仍然不高,似乎没有达到想要的效果,需要进一步改进。
在MySQLJDBC连接字符串中还可以加入参数,
rewriteBatchedStatements=true,mysql默认关闭了batch处理,通过此参数进行打开,这个参数可以重写向数据库提交的SQL语句。
useServerPrepStmts=false,如果不开启(useServerPrepStmts=false),使用com.mysql.jdbc.PreparedStatement进行本地SQL拼装,最后送到db上就是已经替换了?后的最终SQL.
在此稍加改进,连接字符串中加入下面语句(代码构造方法中去掉注释):
connectStr+="?useServerPrepStmts=false&rewriteBatchedStatements=true";
再次执行如下:
Alldown:103498
Convertfinished.
Allspendtime/s:10
同样的数据量,这次执行只花费了10秒,处理效率大大提高.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。