使用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秒,处理效率大大提高.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。