1. 简介

Java Database Connectivity (JDBC) 是 Java 中用于数据库交互的核心 API。批处理技术将多个 SQL 查询打包成一个单元,通过单次网络请求发送给数据库。

本文将深入探讨如何利用 JDBC 实现 SQL 查询的批处理操作。更多 JDBC 基础知识可参考我们的入门教程

2. 为什么需要批处理?

性能优化和数据一致性是采用批处理的核心驱动力。

2.1 性能提升

当需要向数据库插入大量数据时,传统方式是逐条执行 SQL 语句。来看个非批处理的示例:

statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('1','EmployeeName1','Designation1')"); 
statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('2','EmployeeName2','Designation2')");

⚠️ 这种顺序调用会导致频繁的网络往返,性能堪忧

通过批处理,所有查询可一次性发送,显著提升性能。

2.2 数据一致性

某些场景需要同时操作多张表,形成关联事务。执行顺序至关重要,任何错误都应触发回滚。

看个多表操作示例:

statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('1','EmployeeName1','Designation1')"); 
statement.execute("INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) "
 + "VALUES ('10','1','Address')");

典型问题:第一条成功但第二条失败时,已插入的数据不会回滚,导致数据不一致

虽然可以通过事务管理(异常时回滚)解决,但每个语句仍需单独访问数据库,效率低下。

3. 如何实现批处理

JDBC 提供了 StatementPreparedStatement 两个核心类,它们都支持 addBatch()executeBatch() 方法实现批处理。

3.1 使用 Statement 批处理

Statement 是 JDBC 中最基础的查询执行方式。通过 addBatch() 添加 SQL 语句,再用 executeBatch() 统一执行。

executeBatch() 返回 int[] 数组,表示每个 SQL 语句影响的记录数。

示例代码:

Statement statement = connection.createStatement();
statement.addBatch("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('1','EmployeeName','Designation')");
statement.addBatch("INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) "
 + "VALUES ('10','1','Address')");
statement.executeBatch();

这里通过 StatementEMPLOYEEEMP_ADDRESS 表插入数据,展示了批量添加 SQL 语句的流程。

3.2 使用 PreparedStatement 批处理

PreparedStatement 支持预编译 SQL,只需动态更新参数。特别适合相同结构不同值的批量操作。

首先定义 SQL 模板:

String[] EMPLOYEES = new String[]{"Zuck","Mike","Larry","Musk","Steve"};
String[] DESIGNATIONS = new String[]{"CFO","CSO","CTO","CEO","CMO"};

String insertEmployeeSQL = "INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES (?,?,?)";
PreparedStatement employeeStmt = connection.prepareStatement(insertEmployeeSQL);

然后循环设置参数并添加到批处理:

for(int i = 0; i < EMPLOYEES.length; i++){
    String employeeId = UUID.randomUUID().toString();
    employeeStmt.setString(1,employeeId);
    employeeStmt.setString(2,EMPLOYEES[i]);
    employeeStmt.setString(3,DESIGNATIONS[i]);
    employeeStmt.addBatch();
}
employeeStmt.executeBatch();

优势:只需编译一次 SQL,通过参数化设置高效处理批量数据。

4. 总结

本文深入分析了 JDBC 批处理的核心价值:

  • 显著减少网络开销,提升性能
  • 结合事务管理确保数据一致性
  • 通过 StatementPreparedStatement 提供灵活实现

完整代码示例可在 GitHub 获取。实际开发中,建议优先使用 PreparedStatement 处理批量操作,既安全又高效。


原始标题:Batch Processing in JDBC | Baeldung