executebatch()返回int[]数组,每个元素对应一条addbatch()语句的影响行数:≥0为实际行数,-2表示成功但行数未知,-3表示执行失败;需注意数据库驱动差异及mysql等默认返回-2的问题。

在 Java 中使用 JDBC 执行批处理(addBatch() + executeBatch())后,可以通过 executeBatch() 的返回值获取每条语句实际影响的行数,但需注意前提条件和常见陷阱。
确保数据库和驱动支持返回行数
不是所有数据库或 JDBC 驱动都默认返回每条批处理语句的影响行数。例如:
- MySQL Connector/J 默认返回
-2(Statement.SUCCESS_NO_INFO),除非显式启用; - PostgreSQL 的
pgjdbc支持返回真实行数(如INSERT/UPDATE/DELETE); - Oracle 的
ojdbc在开启returning或使用executeBatch()时,对 DML 语句通常返回准确数值。
建议连接时添加参数(以 MySQL 为例):?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true
其中 rewriteBatchedStatements=true 不仅提升性能,还让驱动将批量 INSERT 重写为多值单语句,此时 executeBatch() 返回的是总行数(而非数组),但可通过 getUpdateCount() 或驱动特定方式间接统计 —— 更稳妥的做法是使用标准批处理并检查返回数组。
正确读取 executeBatch() 的返回值
executeBatch() 返回 int[],每个元素对应一次 addBatch() 调用的影响行数:
-
>= 0:表示该语句影响的具体行数(如1,3); -
Statement.SUCCESS_NO_INFO(值为-2):表示执行成功,但驱动无法提供具体行数; -
Statement.EXECUTE_FAILED(值为-3):表示该条执行失败(批处理未全部回滚,取决于是否启用continueBatchOnError)。
示例代码片段:
PreparedStatement ps = conn.prepareStatement("UPDATE users SET name = ? WHERE id = ?");
ps.setString(1, "Alice"); ps.setInt(2, 1); ps.addBatch();
ps.setString(1, "Bob"); ps.setInt(2, 2); ps.addBatch();
ps.setString(1, "Carol"); ps.setInt(2, 999); ps.addBatch(); // 假设 id=999 不存在
int[] rows = ps.executeBatch();
for (int i = 0; i
<h3>区分“受影响行数”与“匹配行数”</h3>
<p>尤其在 MySQL 中,<code>UPDATE</code> 语句默认返回“实际被修改的行数”(即内容未变则计为 0),而非“WHERE 匹配到的行数”。若需后者,可在连接 URL 中添加:<br><font color="gray"><code>&useAffectedRows=false</code></font><br>
这样 MySQL 驱动会返回匹配行数(即使字段值未变)。PostgreSQL 和 Oracle 则通常返回实际变更行数,行为更一致。</p>
<h3>替代方案:手动统计(适用于不支持或不可靠场景)</h3>
<p>当驱动始终返回 <code>-2</code> 或业务逻辑要求精确控制时,可改用单条执行 + 显式计数:</p>
- 对每条 SQL 单独
executeUpdate(),累加返回值; - 或先用
SELECT COUNT(*)预查匹配行数(适合 UPDATE/DELETE 前预估); - 对批量 INSERT,若主键/唯一约束不冲突,插入行数即为
addBatch()次数(但无法感知跳过或失败)。
该方式牺牲性能换确定性,适合小批量或关键审计场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











