在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据。此外,我们将努力探索一些场景,如在内存不足时正常运行,以及如何优化批量操作。


首先,使用Java JDBC基本的API批量插入数据到数据库中。

Simple Batch - 简单批处理
    我把它叫做简单批处理。要求很简单,执行批量插入列表,而不是为每个INSERT语句每次提交数据库,我们将使用JDBC批处理操作和优化性能。

想想一下下面的代码:

Bad Code
String [] queries = {"insert into employee (name, city, phone) values ('A', 'X', '123')","insert into employee (name, city, phone) values ('B', 'Y', '234')","insert into employee (name, city, phone) values ('C', 'Z', '345')",};
Connection connection = new getConnection();
Statement statemenet = connection.createStatement();for (String query : queries) {statemenet.execute(query);
}
statemenet.close();
connection.close();

这是糟糕的代码。它单独执行每个查询,每个INSERT语句的都提交一次数据库。考虑一下,如果你要插入1000条记录呢?这是不是一个好主意。

下面是执行批量插入的基本代码。来看看:

Good Code

Connection connection = new getConnection();
Statement statemenet = connection.createStatement();for (String query : queries) {statemenet.addBatch(query);
}
statemenet.executeBatch();
statemenet.close();
connection.close();

请注意我们如何使用addBatch()方法,而不是直接执行查询。然后,加入所有的查询,我们使用statement.executeBatch()方法一次执行他们。没有什么花哨,只是一个简单的批量插入。

请注意,我们已经从一个String数组构建了查询。现在,你可能会想,使其动态化。例如:

import java.sql.Connection;
import java.sql.Statement;
//...
Connection connection = new getConnection();
Statement statemenet = connection.createStatement();
for (Employee employee: employees) {String query = "insert into employee (name, city) values('"+ employee.getName() + "','" + employee.getCity + "')";statemenet.addBatch(query);
}
statemenet.executeBatch();
statemenet.close();
connection.close();

请注意我们是如何从Employee对象中的数据动态创建查询并在批处理中添加,插入一气呵成。完美!是不是?

等等......你必须思考什么关于SQL注入?这样动态创建的查询SQL注入是很容易的。并且每个插入查询每次都被编译。

为什么不使用PreparedStatement而不是简单的声明。是的,这是个解决方案。下面是SQL注入安全批处理。

SQL Injection Safe Batch - SQL注入安全批处理
思考一下下面代码:

import java.sql.Connection;
import java.sql.PreparedStatement;//...
String sql = "insert into employee (name, city, phone) values (?, ?, ?)";
Connection connection = new getConnection();
PreparedStatement ps = connection.prepareStatement(sql);for (Employee employee: employees) {ps.setString(1, employee.getName());ps.setString(2, employee.getCity());ps.setString(3, employee.getPhone());ps.addBatch();
}
ps.executeBatch();
ps.close();
connection.close();

看看上面的代码。漂亮。我们使用的java.sql.PreparedStatement和在批处理中添加INSERT查询。这是你必须实现批量插入逻辑的解决方案,而不是上述Statement那个。

这一解决方案仍然存在一个问题。考虑这样一个场景,在您想要插入到数据库使用批处理上万条记录。嗯,可能产生的

java.lang.OutOfMemoryError: Java heap space
com.mysql.jdbc.ServerPreparedStatement$BatchedBindValues.<init>(ServerPreparedStatement.java:72)
com.mysql.jdbc.ServerPreparedStatement.addBatch(ServerPreparedStatement.java:330)
org.apache.commons.dbcp.DelegatingPreparedStatement.addBatch(DelegatingPreparedStatement.java:171)

这是因为你试图在一个批次添加所有语句,并一次插入。最好的办法是将执行分批次。看看下面的解决方案

Smart Insert: Batch within Batch - 智能插入:将整批分批
这是一个简单的解决方案。考虑批量大小为1000,每1000个查询语句为一批插入提交。

String sql = "insert into employee (name, city, phone) values (?, ?, ?)";
Connection connection = new getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
final int batchSize = 1000;
int count = 0;
for (Employee employee: employees) {ps.setString(1, employee.getName());ps.setString(2, employee.getCity());ps.setString(3, employee.getPhone());ps.addBatch();if(++count % batchSize == 0) {ps.executeBatch();}
}
ps.executeBatch(); // insert remaining records
ps.close();
connection.close();

这才是理想的解决方案,它避免了SQL注入和内存不足的问题。看看我们如何递增计数器计数,一旦BATCHSIZE 达到 1000,我们调用executeBatch()提交。

注*:转自:http://www.cnblogs.com/kahreman/archive/2012/08/06/2625827.html

转载于:https://www.cnblogs.com/gisblogs/p/3966399.html

Java JDBC批处理插入数据操作相关推荐

  1. java jdbc 批处理_Java JDBC批处理插入数据操作

    在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...

  2. JDBC批处理插入更新MySQL Oracle

    Today we will look into JDBC Batch insert and update examples in MySQL and Oracle databases. Sometim ...

  3. java向mysql插入数据乱码问题解决

    java向mysql插入数据乱码问题解决 参考文章: (1)java向mysql插入数据乱码问题解决 (2)https://www.cnblogs.com/jack204/archive/2012/0 ...

  4. java向数据库插入数据时的错误: Duplicate entry ‘‘ for key ‘PRIMARY‘ 问题解决

    java向数据库插入数据时的错误: Duplicate entry '' for key 'PRIMARY' 问题解决 参考文章: (1)java向数据库插入数据时的错误: Duplicate ent ...

  5. unordered_multimap学习之插入数据操作insert,emplace ,emplace_hint

    本篇学习unordered_multimap的插入数据操作,具体的函数如下: insert (C++11) 插入元素或结点 (C++17 起) (公开成员函数) emplace (C++11) 原位构 ...

  6. JDBC进行批量插入数据操作

    目录 1.方式一:使用PreparedStatement 2.方式二:使用addBatch(),excuteBatch(),clearBatch() 3.方式三:设置不允许自动提交数据 4.总结 1. ...

  7. JDBC 批量插入数据

    当需要批量插入数据到数据库时,我们可以利用基础的Statement或PreparedStatement外加for循环来实现操作,但这种方式效率奇低. 因此,当需要成批插入或者更新记录时,我们可以利用J ...

  8. JDBC批量插入数据优化,使用addBatch和executeBatch

    >>.在之前的玩转JDBC打造数据库操作万能工具类JDBCUtil,加入了高效的数据库连接池,利用了参数绑定有效防止SQL注入 中其实忽略了一点,那就是SQL的批量插入的问题,如果来个fo ...

  9. java处理word插入数据转PDF及下载PDF

    欢迎使用Markdown编辑器 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.引入jar包 二.使用步骤 1.前端上传电子签名图片 2.java下载电子签名图片 ...

最新文章

  1. CSS之布局(行内元素的盒模型)
  2. Java程序设计第三次作业
  3. IIS报错,App_global.asax.×××.dll拒绝访问
  4. PHP内置函数生成随机数的方法汇总
  5. zzlinux运维自动化shell脚本小工具
  6. boost::geometry::topological_dimension用法的测试程序
  7. dedecms /include/uploadsafe.inc.php SQL Injection Via Local Variable Overriding Vul
  8. PostgreSQL的中文拼音排序
  9. ThinkPHP文件上传类的使用
  10. 梅森旋转产生随机数c语言实现,梅森旋转法产生随机数
  11. 英特尔:赔你15亿算了;Nvidia:反正我早就不做你那块了
  12. green: JRE + Tomcat + Mysql - JaveEE JTM0.9
  13. Mysql的持久层_持久层(数据层,Dao层) MyBatis框架
  14. 百度富文本编辑器的宽度自适应
  15. Lunar Pro for Mac v5.2.2 – 实用的外接显示器屏幕亮度调节工具
  16. 高德纳(Donald Knuth)语录
  17. Doevent()理解
  18. matlab gui下拉列表,MATLAB制作GUI(3)-下拉列表的实现
  19. CToolBar的使用总结(转1)
  20. QMI8658 - 姿态传感器学习笔记 - Ⅲ

热门文章

  1. 浅析网站优化知识自学从哪些方面开始起步
  2. 二级域名做SEO优化有怎样的利弊关系?
  3. java mina 长连接_apache mina 长连接
  4. opengl 深度详解_一步步学OpenGL(1) -《打开一个窗口》
  5. 获取预制体_基于弱磁探测技术的轴承滚动体转速检测方法研究
  6. 不等距双杆模型_气体中的变质量模型
  7. HDFS 文件格式——SequenceFile RCFile
  8. kafka备份机制——zk选举leader,leader在broker里负责备份
  9. sphinx索引分析续
  10. spark streaming 入门例子