La segunda forma es un poco más eficiente, pero una forma mucho mejor es ejecutarlos en lotes:
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();
}
}
Sin embargo, depende de la implementación del controlador JDBC cuántos lotes puede ejecutar a la vez. Por ejemplo, puede querer ejecutarlos cada 1000 lotes:
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.
}
}
}
}
En cuanto a los entornos multiproceso, no necesita preocuparse por esto si adquiere y cierra la conexión y la declaración en el alcance más corto posible dentro del mismo bloque de método de acuerdo con el idioma JDBC normal usando la declaración try-with-resources como se muestra en fragmentos anteriores.
Si esos lotes son transaccionales, entonces le gustaría desactivar la confirmación automática de la conexión y solo confirmar la transacción cuando todos los lotes estén terminados. De lo contrario, puede resultar en una base de datos sucia cuando el primer grupo de lotes tuvo éxito y el posterior no.
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;
}
}
}
}
sql
¿ su consulta no cambia con el bucle? Si esa consulta no cambia para cada iteración del ciclo, ¿por qué está creando una nuevaPreparedStatement
para cada iteración (en el primer fragmento de código)? ¿Hay alguna razón para hacerlo?