`

强大的批处理功能

    博客分类:
  • 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那个。

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

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()提交。
分享到:
评论

相关推荐

    非常好用的批处理功能强大

    批处理文件通常以`.bat`或`.cmd`为扩展名,但在提供的信息中,我们看到的是一个名为"批处理.exe"的文件,这可能是一个批处理脚本封装在可执行程序中,以提供更方便的用户界面或者增加额外的功能。 批处理的基础知识...

    ILASII系统数据批处理功能研究

    ILASII(Integrated Library Automation System II)系统是一款广泛应用的图书馆自动化管理系统,它提供了高效的数据接口和强大的数据批处理功能,旨在优化图书馆的日常运营。数据批处理允许图书馆员批量处理大量...

    非常批处理(功能强大)

    在"非常批处理"这个案例中,我们可以理解它是一个设计得相当简洁且功能强大的批处理脚本,旨在提高工作效率,减少用户手动操作的繁琐。 批处理脚本的优点主要体现在以下几个方面: 1. **自动化重复任务**:如果你...

    usb屏蔽批处理,功能强大

    在标题“usb屏蔽批处理,功能强大”中,我们可以理解这是一种使用批处理脚本来实现USB端口禁用的功能,它具有高效且易于操作的特点。 批处理文件(.bat)是Windows操作系统中的一种文本文件,它包含了一系列命令,...

    强大好用批处理集合

    "大型&综合性脚本"可能包含的是解决特定问题或完成复杂任务的批处理文件,它们可能整合了多个命令和功能,例如文件的批量移动、复制、删除,或者系统设置的批量更改。 "字符串提取&替换等操作"是批处理中的高级技巧...

    万能批处理工具,功能强大

    万能批处理工具,功能强悍,保证好用,简单使用

    万能批处理,功能强大呀

    【万能批处理,功能强大呀】 批处理(Batch Processing)是一种在计算机系统中用于处理大量数据或执行一系列命令的自动化技术。它允许用户通过编写脚本文件(通常以批处理命令的形式)来批量执行一系列操作,从而...

    功能强大的批处理文件

    功能强大的批处理文件,找了很久才找到的,与大家共享。

    万能批处理工具包 bat 下载 源代码 功能强大

    万能批处理工具包 bat 下载 源代码 功能强大

    批处理之家论坛下载批处理实例

    Sed是一个功能强大的文本处理工具,可以进行模式匹配、替换、删除、插入等操作,常用于自动化文本处理任务。 关于批处理的基础知识,我们可以深入探讨以下几个方面: 1. **批处理文件格式**:批处理文件通常以扩展...

    批处理学习和批处理实例

    批处理文件通常以`.cmd`或`.bat`为扩展名,这两种格式在功能上基本相同,都是用来运行DOS命令的文本文件。 批处理的学习可以从以下几个方面入手: 1. **基础语法**:批处理脚本中的命令行与DOS命令类似,如`echo`...

    批处理,超级好玩的批处理

    6. **学习与调试**:学习批处理脚本通常需要动手实践,可以创建简单的批处理文件,逐步添加复杂功能。调试时,可以通过`Echo.`打印变量或命令结果,`PAUSE`让脚本暂停以查看状态,或者使用`@echo on`打开命令回显以...

    一键打开IIS功能批处理(支持IIS8及以下版本)

    标题中的“一键打开IIS功能批处理”指的是通过批处理脚本快速启用Windows操作系统中的Internet Information Services(IIS)服务。IIS是微软提供的一个用于创建和管理Web服务器的组件,它允许用户托管网站、应用程序...

    批处理日历、批处理时钟

    总的来说,这个批处理日历和时钟项目展示了批处理的强大之处,即用简单的文本文件实现复杂的功能。它结合了DOS命令、条件判断和外部程序调用,为用户提供了便捷的时间查询工具,同时增添了趣味性。学习和理解这样的...

    批处理文件批处理文件制作

    批处理文件,也被称为批处理脚本或BAT文件,是Windows操作系统中的一种命令行工具,用于自动化执行一系列的命令操作。...通过深入学习和实践,你可以创建出强大的批处理脚本来解决日常的电脑操作问题,提高工作效率。

    批处理大全_很多批处理都在这里

    通过熟练运用这些命令,可以创建出功能强大的批处理程序。 学习和使用批处理,不仅可以提高个人工作效率,对于系统管理员和程序员来说,也是必备技能之一。通过批处理,可以实现一些简单的自动化流程,甚至可以作为...

    DOS批处理编译器 DOS软件

    总之,DOS批处理编译器如VisualBat是提高DOS系统中自动化任务效率的有效工具,它通过图形化的界面和强大的功能,降低了批处理脚本的编写门槛,同时也提高了脚本的质量和执行效率。对于需要在DOS环境中处理大量重复...

    批处理文件编程指南

    掌握这些基本命令和高级特性,你就能编写出强大的批处理脚本来自动化日常任务,提高工作效率。批处理编程虽然在图形界面丰富的现代操作系统中可能显得较为古老,但在特定场景下,它仍然是快速解决问题的有效工具。

    DOS批处理教程 批处理

    通过掌握上述基础知识和高级技巧,可以编写出功能强大且灵活的批处理脚本。在实际应用中,还可以结合外部工具进一步增强批处理的功能性和实用性。希望本文能为大家提供一个全面的学习指南,助力大家更好地掌握DOS...

    ArcGIS教程:ArcGIS中的批处理

    在 ArcGIS 中,Buffer 工具提供了批处理功能,可以实现批量创建缓冲区。下面是使用 Buffer 工具的批处理步骤: 1. 首先,需要在道路数据中添加一个属性字段来存储 Buffer 宽度信息。 2. 应用 Buffer 工具,在对应的...

Global site tag (gtag.js) - Google Analytics