PreparedStatement批量插入核心在于预编译+批处理+合理参数绑定,需关闭自动提交、设置rewriteBatchedStatements=true(MySQL)、复用同一实例、批次大小控制在500–5000。

使用 PreparedStatement 批量插入时,核心不是“单条 SQL 用 PreparedStatement 就快”,而是通过 预编译 + 批处理 + 合理参数绑定 减少数据库往返和解析开销。关键在于开启批处理模式并控制批次大小。
开启批处理并分批执行
直接调用 addBatch() 累积多条语句,再统一 executeBatch() 提交,避免每条都走网络和解析流程:
- 先创建带占位符的
PreparedStatement(如"INSERT INTO user(name, age) VALUES (?, ?)") - 循环中调用
setString(1, name)、setInt(2, age)绑定参数,再调用addBatch() - 每累积一定数量(如 1000 条)就调用
executeBatch(),并清空批次:clearBatch() - 循环结束后别忘了执行剩余未提交的批次
启用重写批量插入(MySQL 特有优化)
MySQL 驱动支持将多个 INSERT 自动合并为一条多值语句(如 INSERT INTO t VALUES(?,?),(?,?)),需在连接 URL 中显式开启:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 添加参数:
&rewriteBatchedStatements=true - 例如:
jdbc:mysql://localhost:3306/test?useSSL=false&rewriteBatchedStatements=true - 开启后,1000 次
addBatch()可能只生成 1 条物理 SQL,性能提升可达 3~10 倍 - 注意:仅对
INSERT有效,UPDATE/DELETE不适用;且要求驱动版本 ≥ 5.1.13
关闭自动提交并手动事务控制
默认每条 executeBatch() 都隐式提交,I/O 和日志开销大。应关闭自动提交,把整批操作包在一个事务里:
立即学习“Java免费学习笔记(深入)”;
-
connection.setAutoCommit(false)在批量前调用 - 所有
executeBatch()完成后,调用connection.commit() - 发生异常时,及时
connection.rollback() - 避免在循环内频繁 commit,也别让事务过大导致锁表或回滚日志膨胀
其他实用细节
小但影响明显的点:
-
不要在循环里反复
prepareStatement()—— 必须复用同一个PreparedStatement实例 - 批次大小建议 500–5000,太小起不到批处理效果,太大易 OOM 或锁等待过长
- Oracle 用户可考虑
addBatch()配合executeBatch(),但更推荐OraclePreparedStatement的setExecuteBatch()+executeUpdate()流式提交 - PostgreSQL 推荐用
copy协议(如CopyManager)替代 JDBC 批量,速度更快

















