使用JDBC在MySQL数据库中如何快速批量插入数据
作者:PlusPlus1 发布时间:2024-01-18 04:04:13
使用JDBC连接MySQL数据库进行数据插入的时候,特别是大批量数据连续插入(10W+),如何提高效率呢?
在JDBC编程接口中Statement 有两个方法特别值得注意:
void addBatch() throws SQLException
Adds a set of parameters to this PreparedStatement object's batch of commands.
int[] executeBatch() throws SQLException
Submits a batch of commands to the database for execution and if all commands execute successfully, returns an array of update counts. The int elements of the array that is returned are ordered to correspond to the commands in the batch, which are ordered according to the order in which they were added to the batch.
通过使用addBatch()和executeBatch()这一对方法可以实现批量处理数据。
不过值得注意的是,首先需要在数据库链接中设置手动提交,connection.setAutoCommit(false),然后在执行Statement之后执行connection.commit()。
package cyl.demo.ipsearcher;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class DbStoreHelper {
private String insert_sql;
private String charset;
private boolean debug;
private String connectStr;
private String username;
private String password;
public DbStoreHelper() {
connectStr = "jdbc:mysql://localhost:3306/db_ip";
// connectStr += "?useServerPrepStmts=false&rewriteBatchedStatements=true";
insert_sql = "INSERT INTO tb_ipinfos (iplong1,iplong2,ipstr1,ipstr2,ipdesc) VALUES (?,?,?,?,?)";
charset = "gbk";
debug = true;
username = "root";
password = "***";
}
public void storeToDb(String srcFile) throws IOException {
BufferedReader bfr = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile), charset));
try {
doStore(bfr);
} catch (Exception e) {
e.printStackTrace();
} finally {
bfr.close();
}
}
private void doStore(BufferedReader bfr) throws ClassNotFoundException, SQLException, IOException {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(connectStr, username,password);
conn.setAutoCommit(false); // 设置手动提交
int count = 0;
PreparedStatement psts = conn.prepareStatement(insert_sql);
String line = 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("All down : " + count);
conn.close();
}
}
执行完成以后:
All down : 103498
Convert finished.
All spend time/s : 47
一共10W+,执行时间一共花费 47 秒.
这个效率仍然不高,似乎没有达到想要的效果,需要进一步改进。
在MySQL JDBC连接字符串中还可以加入参数,
rewriteBatchedStatements=true,mysql默认关闭了batch处理,通过此参数进行打开,这个参数可以重写向数据库提交的SQL语句。
useServerPrepStmts=false,如果不开启(useServerPrepStmts=false),使用com.mysql.jdbc.PreparedStatement进行本地SQL拼装,最后送到db上就是已经替换了?后的最终SQL.
在此稍加改进,连接字符串中加入下面语句(代码构造方法中去掉注释):
connectStr += "?useServerPrepStmts=false&rewriteBatchedStatements=true";
再次执行如下:
All down : 103498
Convert finished.
All spend time/s : 10
同样的数据量,这次执行只花费了10秒 ,处理效率大大提高.


猜你喜欢
- 本文实例为大家分享了python3判断IP地址的具体代码,供大家参考,具体内容如下输入一串字符,判断该字符串是否为点分十进制的IP地址,若是
- 我们在做诸如人群密集度等可视化的时候,可能会考虑使用热力图,在Python中能很方便地绘制热力图。下面以识别图片中的行人,并绘制热力图为例进
- 在python中,如下代码结果一定不会让你吃惊:Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013
- QueueQueue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生
- 前言最近在使用Pycharm,在运行或者安装的过程中出现了各种各样的报错,前面已经介绍过安装pygame出现报错的解决方法。文章总结了大部分
- 本文实例讲述了JavaScript让Textarea支持tab按键的方法。分享给大家供大家参考。具体实现方法如下:HTMLTextAreaE
- 存储过程的优缺点: 存储过程优点: 1.由于应用程序随着时间推移会不断更改,增删功能,T-SQL过程代码会变得更复杂,StoredProce
- 本文实例讲述了Python单例模式的使用方法。分享给大家供大家参考。具体如下:方法一import threading
- 熟悉web开发的同学对hook钩子肯定不陌生,通过钩子可以方便的实现一些触发和回调,并且做一些过滤和拦截。django中的中间件(middl
- bootstrap自带的响应式导航栏是向下滑动的,有时满足不了个性化的需求,需要做一个类似于android drawerLayout 侧滑的
- 本文实例讲述了Python实现压缩与解压gzip大文件的方法。分享给大家供大家参考,具体如下:#encoding=utf-8#author:
- Python 截取字符串使用 变量[头下标:尾下标],就可以截取相应的字符串,其中下标是从0开始算起,可以是正数或负数,下标可以为空表示取到
- 今天在写一个算法的过程中,得到了一个类似下面的字典:{'user1':0.456,'user2':0.999
- 概述在JavaScript前端开发中,函数与对其状态即词法环境(lexical environment)的引用共同构成闭包(closure)
- 编号标准宗地编码(landCode)所在区段编码(sectCode)1131001BG001G0012131001BG002G0013131
- 网站或服务的性能关键点很大程度在于数据库的设计(假设你选择了合适的语言开发框架)以及如何查询数据上。我们知道MySQL的性能优化方法,一般有
- Mac 安装Mysql有许多开发的小伙伴,使用的是mac,那么在mac上如何安装Mysql呢?这篇文章就给大家说说。1、首先,登陆Mysql
- 今天有人问起,晚上试着写出来,供参考; 以下代码兼容主流浏览器IE6、IE7、Firefox、Opera。从最简单的开始…………一
- 昨天我突发奇想,想用display:inline来实现三列的布局可是搞了半天就是不行。但是理论上是可以的呀(后来才发现是不理解的不深刻,我的
- 一、我的需求对于这样的一个 csv 表,需要将其(1)将营业部名称和日期和股票代码进行拼接(2)对于除了买入金额不同的的数据需要将它们的买入