第二种方法更有效率,但更好的方法是批量执行它们:
public void executeBatch(List<Entity> entities) throws SQLException {
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL);
) {
for (Entity entity : entities) {
statement.setObject(1, entity.getSomeProperty());
// ...
statement.addBatch();
}
statement.executeBatch();
}
}
但是,您依赖于 JDBC 驱动程序实现可以一次执行多少个批处理。例如,您可能希望每 1000 个批次执行一次:
public void executeBatch(List<Entity> entities) throws SQLException {
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL);
) {
int i = 0;
for (Entity entity : entities) {
statement.setObject(1, entity.getSomeProperty());
// ...
statement.addBatch();
i++;
if (i % 1000 == 0 || i == entities.size()) {
statement.executeBatch(); // Execute every 1000 items.
}
}
}
}
至于多线程环境,如果您根据正常的JDBC习语使用 try-with-resources语句(如上面的片段所示)在同一方法块内的最短范围内获取并关闭连接和语句,则无需担心这一点。
如果这些批处理是事务性的,则您希望关闭连接的自动提交,并仅在所有批处理完成后提交事务。否则,当第一组批处理成功而后一组批处理不成功时,可能会导致数据库脏。
public void executeBatch(List<Entity> entities) throws SQLException {
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);
try (PreparedStatement statement = connection.prepareStatement(SQL)) {
// ...
try {
connection.commit();
} catch (SQLException e) {
connection.rollback();
throw e;
}
}
}
}