Java JDBC批处理插入数据操作
在此笔记里,我们将看到我们如何可以使用像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批处理插入数据操作相关推荐
- java jdbc 批处理_Java JDBC批处理插入数据操作
在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...
- JDBC批处理插入更新MySQL Oracle
Today we will look into JDBC Batch insert and update examples in MySQL and Oracle databases. Sometim ...
- java向mysql插入数据乱码问题解决
java向mysql插入数据乱码问题解决 参考文章: (1)java向mysql插入数据乱码问题解决 (2)https://www.cnblogs.com/jack204/archive/2012/0 ...
- java向数据库插入数据时的错误: Duplicate entry ‘‘ for key ‘PRIMARY‘ 问题解决
java向数据库插入数据时的错误: Duplicate entry '' for key 'PRIMARY' 问题解决 参考文章: (1)java向数据库插入数据时的错误: Duplicate ent ...
- unordered_multimap学习之插入数据操作insert,emplace ,emplace_hint
本篇学习unordered_multimap的插入数据操作,具体的函数如下: insert (C++11) 插入元素或结点 (C++17 起) (公开成员函数) emplace (C++11) 原位构 ...
- JDBC进行批量插入数据操作
目录 1.方式一:使用PreparedStatement 2.方式二:使用addBatch(),excuteBatch(),clearBatch() 3.方式三:设置不允许自动提交数据 4.总结 1. ...
- JDBC 批量插入数据
当需要批量插入数据到数据库时,我们可以利用基础的Statement或PreparedStatement外加for循环来实现操作,但这种方式效率奇低. 因此,当需要成批插入或者更新记录时,我们可以利用J ...
- JDBC批量插入数据优化,使用addBatch和executeBatch
>>.在之前的玩转JDBC打造数据库操作万能工具类JDBCUtil,加入了高效的数据库连接池,利用了参数绑定有效防止SQL注入 中其实忽略了一点,那就是SQL的批量插入的问题,如果来个fo ...
- java处理word插入数据转PDF及下载PDF
欢迎使用Markdown编辑器 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.引入jar包 二.使用步骤 1.前端上传电子签名图片 2.java下载电子签名图片 ...
最新文章
- CSS之布局(行内元素的盒模型)
- Java程序设计第三次作业
- IIS报错,App_global.asax.×××.dll拒绝访问
- PHP内置函数生成随机数的方法汇总
- zzlinux运维自动化shell脚本小工具
- boost::geometry::topological_dimension用法的测试程序
- dedecms /include/uploadsafe.inc.php SQL Injection Via Local Variable Overriding Vul
- PostgreSQL的中文拼音排序
- ThinkPHP文件上传类的使用
- 梅森旋转产生随机数c语言实现,梅森旋转法产生随机数
- 英特尔:赔你15亿算了;Nvidia:反正我早就不做你那块了
- green: JRE + Tomcat + Mysql - JaveEE JTM0.9
- Mysql的持久层_持久层(数据层,Dao层) MyBatis框架
- 百度富文本编辑器的宽度自适应
- Lunar Pro for Mac v5.2.2 – 实用的外接显示器屏幕亮度调节工具
- 高德纳(Donald Knuth)语录
- Doevent()理解
- matlab gui下拉列表,MATLAB制作GUI(3)-下拉列表的实现
- CToolBar的使用总结(转1)
- QMI8658 - 姿态传感器学习笔记 - Ⅲ