`
baobeituping
  • 浏览: 1067920 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

JAVA采用JDBC执行批处理操作注意的问题

 
阅读更多

让我们看看如何使用JDBC API在Java中执行批量插入。虽然你可能已经知道,但我会尽力解释基础到复杂的场景。

 
在此笔记里,我们将看到我们如何可以使用像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()提交。

 希望对你有帮助。

分享到:
评论

相关推荐

    使用JDBC的批处理功能

    4. 执行批处理。 ```java int[] updateCounts = stmt.executeBatch(); ``` 5. 处理结果,检查每个SQL语句的执行情况。 ```java for (int i : updateCounts) { if (i &gt; 0) { System.out.println("语句" + (i+1) + ...

    JDBC数据库操作值MySQL批处理操作

    本文将深入探讨JDBC在MySQL数据库中的应用,以及如何实现批处理操作。 首先,理解JDBC的基础知识至关重要。JDBC是Java平台的标准,由Sun Microsystems(现为Oracle公司)开发,使得Java应用程序能够与多种数据库...

    JDBC进行批处理共4页.pdf.zip

    3. **异常处理**:在执行批处理时,务必捕获并处理SQLException,避免因单个错误导致整个批处理失败。 批处理在实际应用中的场景: 1. **大数据导入**:在数据迁移、数据同步等场景,批处理能大幅提升数据插入速度...

    JDBC高级批处理

    很多数据库管理工具如MySQL Workbench、Navicat等也支持批处理操作,可以在图形界面中方便地组织和执行批处理脚本。 总结,JDBC的高级批处理功能是处理大数据量场景的重要手段,通过合理运用批处理,可以显著提升...

    jdbc 批处理.rar

    3. **执行批处理**:一旦批处理队列中有足够的语句,你可以使用`executeBatch()`方法来执行所有的SQL语句。这将一次性提交所有批处理中的语句,从而提高效率。 4. **事务管理**:批处理通常与事务管理紧密结合。在...

    java之jdbc项目文件

    Java JDBC(Java Database Connectivity)是Java编程语言中用于与数据库交互的一组接口和类,它提供了标准的方法来连接、查询和操作数据库。本项目文件"java之jdbc项目文件"涵盖了使用JDBC进行数据库操作的基本概念...

    Java jdbc操作mysql

    Java JDBC(Java Database Connectivity)是Java语言中用来规范客户端程序如何访问数据库的应用程序接口,它提供了标准的方法来连接、查询和操作MySQL这样的关系型数据库。MySQL是一款开源、免费的SQL数据库,广泛...

    sql2000+java 批处理,测试demo

    这些库对于连接SQL Server 2000和执行批处理操作至关重要。"Pro.bat"很可能是项目的启动脚本,一个批处理文件,用于设置环境变量,定位到Java虚拟机(JVM),并运行主类,从而启动这个批处理系统。 总的来说,这个...

    java_jdbc  

    在进行JDBC操作时,需要注意捕获SQLException及其子类异常,确保程序的健壮性。常见的异常有SQLSyntaxErrorException(SQL语法错误)、SQLException(一般数据库异常)、BatchUpdateException(批处理异常)等。 6...

    javajdbc

    - 利用JDBC的批处理功能执行大量插入、更新操作。 总之,Java JDBC为Java开发者提供了灵活且强大的数据库访问能力,使得开发人员能够方便地进行数据查询、插入、更新和删除等操作,同时支持多种数据库系统,确保了...

    Java用JDBC实现对Oracle数据库操作

    标题“Java用JDBC实现对Oracle数据库操作”主要涉及Java编程语言如何利用Java Database Connectivity (JDBC) API来与Oracle数据库进行交互。JDBC是Java中用于与各种数据库通信的标准接口,而Oracle数据库是一个广泛...

    javajdbc宠物商店-Mysql数据库_Java项目jdbc_java宠物项目_数据库代码_

    这些操作通过编写适当的SQL语句并通过JDBC执行。 8. **异常处理**: 在进行数据库操作时,可能出现各种异常,如`SQLException`。Java的异常处理机制(try-catch-finally)可以捕获并处理这些异常,保证程序的健壮性...

    java批处理

    Java批处理是一种在大型系统中处理大量数据的高效方法,特别是在与数据库进行交互时,它能够显著提升性能和效率。批量处理技术的核心是通过减少单个请求的频率,而是将多个请求合并为一个批次,从而减少了网络延迟和...

    java,JDBC例子

    它是Java标准版(Java SE)的一部分,允许Java开发者在应用程序中执行SQL语句,从而实现对数据库的操作,如查询、插入、更新和删除数据。 在Java中,JDBC提供了一种统一的API,使得开发者无需关心底层数据库的具体...

    java(jdbc)学习

    JDBC(Java Database Connectivity)是一种用于执行SQL语句的Java API,它为数据库开发人员提供了一种标准的API来访问多种类型的数据库,无论是关系型数据库还是非关系型数据库。JDBC位于Java应用程序和数据库驱动...

    (java)JDBC_example.rar_JDBC例子_jdbc_jdbc Java

    - 使用批处理操作批量执行SQL,减少网络交互次数。 5. **JDBC的挑战与注意事项** - 需要正确处理异常,确保资源及时关闭,防止内存泄漏。 - 不同数据库厂商的驱动可能对SQL语法支持不同,编写通用代码时需谨慎。...

    Java JDBC规范和用例

    JDBC的出现解决了Java应用与不同数据库之间交互的兼容性问题,实现了Java程序与数据库的无缝对接。它在物理层面表现为一系列Java类库,而在逻辑上,则被视为调用方(通常是Java开发者)与实现方(数据库供应商)之间...

    JDBC批处理数据

    下面将详细介绍如何使用JDBC API实现批处理操作: ### 示例代码分析 #### 1. 原始的非批处理方式 ```java String[] queries = { "insert into employee(name, city, phone) values('A', 'X', '123')", "insert ...

    JAVA的JDBC学习遇到的问题1

    这篇博客"JAVA的JDBC学习遇到的问题1"可能是作者在深入学习JDBC时遇到的一些常见挑战和解决方法的记录。虽然没有具体的描述内容,我们可以根据一般的学习路径来探讨JDBC相关的知识点。 1. **JDBC基本概念**:首先,...

    JAVA连接数据库JDBC

    JDBC允许Java开发者执行SQL语句并处理结果。在Java应用中,使用JDBC可以实现数据的增删查改操作,使得Java程序能够与各种数据库系统无缝对接。 在Java中连接数据库,首先需要引入相应的数据库驱动JAR包。对于不同的...

Global site tag (gtag.js) - Google Analytics