Let’s see how we can perform batch insert in Java using JDBC APIs. Although you might already knew this, I will try to explain the basic to a bit complex scenarios.
In this note, we will see how we can use JDBC APIs like Statement and PreparedStatement to insert data in any database in batches. Also we will try to explore scenarios where we can run out of memory and how to optimize the batch operation.
So first, the basic API to Insert data in database in batches using Java JDBC.
Simple Batch
I am calling this a simple batch. The requirement is simple. Execute a list of inserts in batch. Instead of hitting database once for each insert statement, we will using JDBC batch operation and optimize the performance.
Consider the following code:
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();
This is the BAD code. You are executing each query separately. This hits the database for each insert statement. Consider if you want to insert 1000 records. This is not a good idea.
We’ll below is the basic code to perform batch insert. Check it out:
Good Code
Connection connection = new getConnection();Statement statemenet = connection.createStatement(); for (String query : queries) { statemenet.addBatch(query);}statemenet.executeBatch();statemenet.close();connection.close();
Note how we used addBatch() method of Statement, instead of directly executing the query. And after adding all the queries we executed them in one go using statement.executeBatch() method. Nothing fancy, just a simple batch insert.
Note that we have taken the queries from a String array. Instead you may want to make it dynamically. For example:
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();
Note how we are creating query dynamically using data from Employee object and adding it in batch to insert in one go. Perfect! isn’t it?
wait.. You must be thinking what about SQL Injection? Creating queries like this dynamically is very prone to SQL injection. And also the insert query has to be compiled each time.
Why not to use PreparedStatement instead of simple Statement. Yes, that can be the solution. Check out the below SQL Injection Safe Batch.
SQL Injection Safe Batch
Consider the following code:
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();
Checkout the above code. Beautiful. We used java.sql.PreparedStatement and added insert query in the batch. This is the solution you must implement in your batch insert logic, instead of above Statement one.
Still there is one problem with this solution. Consider a scenario where you want to insert half million records into database using batch. Well, that may generate 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
This is because you are trying to add everything in one batch and inserting once. Best idea would be to execute batch itself in batch. Check out the below solution.
Smart Insert: Batch within Batch
This is a simplest solution. Consider a batch size like 1000 and insert queries in the batches of 1000 queries at a time.
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 recordsps.close();connection.close();
This would be the idea solution. This avoids SQL Injection and also takes care of out of memory issue. Check how we have incremented a counter count and once it reaches batchSize which is 1000, we call executeBatch().
Hope this helps.
分享到:
相关推荐
本项目"javajdbc宠物商店-Mysql数据库"是基于Java JDBC实现的一个宠物商店管理系统的数据库部分,它提供了与MySQL数据库交互的能力。在这个项目中,我们将深入探讨以下几个核心知识点: 1. **JDBC API**: JDBC API...
在Java中,可以使用JDBC的`PreparedStatement`对象的`setBatch()`方法来设置一组SQL插入语句,然后调用`executeBatch()`执行。这种方式允许一次性提交多条SQL,提高了插入效率。 3. Access数据库与Java的链接: ...
JDBC(Java Database Connectivity)是Java编程语言中用于与关系数据库交互的一种标准接口。它是Java平台的标准部分,允许开发人员使用SQL语言在Java应用程序中执行数据库操作。MySQL JDBC驱动,也称为MySQL ...
在实际应用中,"batchinsert"可能是一个包含示例代码的文件,展示了如何使用JDBC批量插入Blob字段的具体实现。通过研究和理解这些代码,你可以更好地掌握批量插入Blob数据的技巧,并根据自己的需求进行调整和优化。 ...
在Java编程领域,JDBC(Java Database Connectivity)是连接Java应用程序和关系数据库的标准接口。本文将深入探讨如何使用JDBC进行批量插入数据,这在处理大量数据时能显著提高性能。 批量插入数据是数据库操作中...
首先,JDBC(Java Database Connectivity)是Java平台中用于与数据库交互的一种规范,它允许程序员使用SQL语句直接操作数据库。在批量插入场景下,JDBC提供了Statement对象的addBatch()和executeBatch()方法,可以将...
《狂神说Java笔记——MySQL和JDBC》是针对Java开发者深入学习数据库管理和JDBC编程的一份详实教程。这份资料主要围绕两个核心主题:MySQL数据库的使用和Java中的JDBC(Java Database Connectivity)技术,旨在帮助...
2. JDBC4:随着Java版本的更新,JDBC4在Java SE 5和6中引入,它扩展了JDBC3的功能,引入了更多的自动类型转换、连接池管理和异常处理机制,使得数据库操作更加便捷。 3. JDBC41:这个版本是在Java SE 7中引入的,...
在`JDBCBatchInsert.java`中,可以看到如何创建PreparedStatement对象,设置占位符,然后多次调用`addBatch()`添加不同的数据,最后调用`executeBatch()`执行批量插入。 2. **使用Statement的batchUpdate()** ...
Java JDBC(Java Database Connectivity)是Java语言中用来规范客户端程序如何访问数据库的应用程序接口,它提供了标准的方法来连接、查询和操作数据库系统。在Java中,JDBC是通过使用驱动程序来实现数据库连接的,...
Java Database Connectivity(JDBC)是Java编程语言中用于与关系型数据库进行交互的一组标准接口和类。它是由Sun Microsystems(现在是Oracle公司的一部分)开发的,为Java开发者提供了访问数据库的能力,无论数据库...
假设我们有一个`JDBCBatch.java`文件,我们可以创建一个`batchInsert()`方法,如下所示: ```java public class JDBCBatch { public void batchInsert(List<MyData> dataList) throws SQLException { try ...
1. **创建(Create)**:在JDBC中,创建数据通常涉及到创建SQL的INSERT语句,用来向数据库表中插入新的记录。通过`PreparedStatement`接口的`executeUpdate()`方法执行这些语句。 2. **读取(Read)**:查询数据是...
Java JDBC(Java Database Connectivity)是Java编程语言与各种数据库交互的一种标准接口,它允许Java程序通过JDBC API连接并操作数据库。在这个“JDBC调用Oracle数据库.rar”压缩包中,包含了一个名为“TestJDBC2”...
在Java编程中,JDBC(Java Database Connectivity)是用于与各种数据库进行交互的一种标准接口。本项目“JDBC连接实现简单学生管理系统”旨在通过JDBC技术,创建一个能够连接数据库并展示人员信息的管理系统。下面...
Spring JDBC是Spring框架的一个重要模块,它为Java开发者提供了与关系数据库交互的抽象层,简化了JDBC(Java Database Connectivity)的使用。本教程通过一个实际案例,将深入讲解Spring JDBC的基本概念、核心组件...
Spring JDBC是Spring框架的一部分,它提供了一种抽象层,使得我们能够更方便地使用Java数据库连接(JDBC)来处理数据库操作,如增删改查(CRUD)。在这个主题下,我们将深入探讨Spring JDBC的核心概念、配置、以及...
4. 最后,在Controller层或其他业务逻辑中调用`batchInsert`方法,传入包含多个User对象的列表,完成批量插入。 为了优化性能,还可以调整Oracle数据库的设置,例如增大批处理大小、禁用 autocommit 等。同时,注意...