Java MySQL 批量插入实现指南
在Java中实现MySQL批量插入有几种高效的方法,可以显著提高数据插入性能,以下是几种常见的实现方式:

使用PreparedStatement的addBatch()和executeBatch()
这是最常用的批量插入方法,比单条插入性能高很多。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class BatchInsertExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/your_database";
String user = "username";
String password = "password";
String sql = "INSERT INTO your_table (column1, column2, column3) VALUES (?, ?, ?)";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 关闭自动提交,提高性能
conn.setAutoCommit(false);
// 添加批量数据
for (int i = 0; i < 1000; i++) {
pstmt.setString(1, "value1_" + i);
pstmt.setInt(2, i);
pstmt.setString(3, "value3_" + i);
pstmt.addBatch();
// 每100条执行一次批量插入,避免内存占用过大
if (i % 100 == 0) {
pstmt.executeBatch();
}
}
// 执行剩余的批量
pstmt.executeBatch();
// 提交事务
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
使用LOAD DATA INFILE(最高效的方法)
对于大量数据插入,LOAD DATA INFILE是最快的方法,比批量插入快20-100倍。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class LoadDataInfileExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/your_database";
String user = "username";
String password = "password";
// 创建临时CSV文件
File csvFile = new File("temp_data.csv");
try (FileWriter writer = new FileWriter(csvFile)) {
// 写入CSV头(可选)
writer.write("column1,column2,column3\n");
// 写入数据
for (int i = 0; i < 10000; i++) {
writer.write(String.format("value1_%d,%d,value3_%d\n", i, i, i));
}
// 使用JDBC执行LOAD DATA INFILE
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement()) {
String loadSql = String.format(
"LOAD DATA LOCAL INFILE '%s' INTO TABLE your_table " +
"FIELDS TERMINATED BY ',' " +
"LINES TERMINATED BY '\n' " +
"IGNORE 1 ROWS", // 如果有头行,忽略第一行
csvFile.getAbsolutePath()
);
stmt.execute(loadSql);
} catch (SQLException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 删除临时文件
csvFile.delete();
}
}
}
使用JPA/Hibernate的批量插入
如果使用JPA/Hibernate,可以通过以下方式实现批量插入:
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
public class JpaBatchInsertExample {
@PersistenceContext
private EntityManager entityManager;
public void batchInsert(List<Entity> entities) {
entityManager.getTransaction().begin();
for (int i = 0; i < entities.size(); i++) {
entityManager.persist(entities.get(i));
// 每20条刷新一次上下文
if (i % 20 == 0) {
entityManager.flush();
entityManager.clear();
}
}
entityManager.getTransaction().commit();
}
}
性能优化建议
- 调整批量大小:通常100-1000条为一个批量大小较合适
- 关闭自动提交:手动控制事务提交
- 使用连接池:如HikariCP提高连接性能
- 调整MySQL参数:
innodb_buffer_pool_sizeinnodb_log_file_sizebulk_insert_buffer_size
- 考虑并行处理:对于超大数据集,可以分片并行插入
注意事项
- 对于LOAD DATA INFILE,需要确保MySQL服务器有访问临时文件的权限
- 大批量插入时注意内存使用,避免一次性加载过多数据
- 考虑使用事务隔离级别,避免锁竞争
- 在生产环境中,建议先在小数据集上测试性能
选择哪种方法取决于你的具体需求、数据量和性能要求,对于大多数应用场景,PreparedStatement的批量插入已经足够高效。

