JDBC + Java - 批量更新疑问



我正在使用Oracle Database 12c和oracle.jdbc.driver.OracleDriver。

批量插入是如何工作的?我知道这是对语句进行分组,但是如果在 preparedStatement.executeBatch 期间发生呢?它是否每批仅执行 1 次插入?

执行批处理的方法更好。这个带有执行外部循环的:

PreparedStatement ps = c.prepareStatement("insert into some_tab(id, val) values (?, ?);");
for (int i = 0; i < 3000; i++) {
ps.setLong(1, i);
ps.setString(2, "value" + i);
if ((i + 1) % 3 == 0) {
ps.addBatch();
}
}
ps.executeBatch();

或者这个 - 循环执行:

PreparedStatement ps = c.prepareStatement("insert into some_tab(id, val) values (?, ?);");
for (int i = 0; i < 3000; i++) {
ps.setLong(1, i);
ps.setString(2, "value" + i);
ps.addBatch();
if ((i + 1) % 3 == 0) {
ps.executeBatch();
}
}
ps.executeBatch();

执行批处理的方法更好。

PreparedStatement.addBatch将当前参数插入到批处理中

将一组参数添加到此 PreparedStatement 对象的命令批中。

preparedStatement.executeBatch将当前批处理发送到数据库。

将一批命令提交到数据库执行

因此,您的代码没有相同的逻辑。一个只会将 1/3 的插入查询添加到批处理中。另一个将每 3 次迭代执行一次批处理。

我会混合使用两者,将每个迭代添加到批处理中,并且每个#迭代,执行它:

while(...){
...
ps.addBatch();    
if ((i + 1) % 3 == 0) { // 3 is just the example, this can be much higher
ps.executeBatch();
}
}
//Send the rest if the loop ended with `(i + 1) % 3 != 0`
ps.executeBatch();

请注意,3 个批次可能没有必要,您可以大幅增加值,但我真的不知道一种"估计"批次大小的方法才能提高效率,我通常使用 1000 个项目的批次,但这并不是理所当然的......

如果在 preparedStatement.executeBatch 期间发生什么?它是否每批仅执行 1 次插入?

我总是看到像包裹一样的批次。

  1. 您编写带有地址的标签(创建准备语句)
  2. 你拿一个盒子,把地址贴在上面
  3. 用参数填充框(多个添加批处理)
  4. 如果框太小,则发送当前框(执行批处理)
  5. 如果仍有项目要发送,请在点 2 重新启动

这个想法是使用包/批处理来限制来自 JDBC 和 DB 的通信次数。

这在引擎盖下是如何工作的并不是真正的答案,也不应该真正成为一个问题。

最新更新