在處理大量數據庫寫入操作時,逐條執行 SQL 語句會產生頻繁的網絡交互,嚴重影響性能。JDBC 提供的批處理機制允許將多條 SQL 語句一次性發送給數據庫執行,配合事務控制可確保數據一致性。本文詳細講解 Statement 與 PreparedStatement 的批處理用法,並給出完整代碼示例。
addBatch(String sql):將 SQL 語句加入批處理隊列。int[] executeBatch():執行批處理,返回每條語句影響的行數組成的數組。addBatch():將預編譯參數加入批處理,防止 SQL 注入,性能更優。setXxx() 設置參數,再調用 addBatch()。import java.sql.*;
import java.util.Arrays;
public class BatchInsertDemo {
static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
static final String USER = "your_user";
static final String PASS = "your_pass";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL, USER, PASS);
// 關鍵:關閉自動提交,開啟事務
conn.setAutoCommit(false);
stmt = conn.createStatement();
// 添加多條 INSERT 語句
stmt.addBatch("INSERT INTO myemp(ename, job) VALUES ('emp1', 'dev')");
stmt.addBatch("INSERT INTO myemp(ename, job) VALUES ('emp2', 'test')");
stmt.addBatch("INSERT INTO myemp(ename, job) VALUES ('emp3', 'ops')");
// 執行批處理
int[] results = stmt.executeBatch();
System.out.println("各條語句影響行數: " + Arrays.toString(results));
// 無異常則提交事務
conn.commit();
System.out.println("批處理提交成功!");
} catch (Exception e) {
e.printStackTrace();
// 發生異常回滾事務
if (conn != null) {
try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); }
}
} finally {
// 資源關閉
try { if (stmt != null) stmt.close(); } catch (SQLException e) { e.printStackTrace(); }
try { if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); }
}
}
}
conn.setAutoCommit(false) 是事務控制的前提,否則每條語句獨立提交,無法回滾。catch 塊中調用 conn.rollback() 保證數據原子性。finally 塊確保連接與語句對象關閉,防止洩漏。String sql = "INSERT INTO myemp(ename, job, sal) VALUES (?, ?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
for (int i = 1; i <= 1000; i++) {
pstmt.setString(1, "emp" + i);
pstmt.setString(2, "dev");
pstmt.setDouble(3, 5000 + i * 10);
pstmt.addBatch();
// 可選:分批提交,避免內存溢出(如每 500 條提交一次)
if (i % 500 == 0) {
pstmt.executeBatch();
conn.commit();
}
}
pstmt.executeBatch(); // 剩餘數據
conn.commit();
PreparedStatement 批處理,兼具安全與性能。掌握 JDBC 批處理與事務控制,是 Java 後端開發處理高吞吐寫入場景的基本功。實際項目中,結合 MyBatis 的 ExecutorType.BATCH 或 Spring 的 @Transactional 註解,能更優雅地實現同樣功能。