Der zweite Weg ist ein bisschen effizienter, aber ein viel besserer Weg ist, sie in Stapeln auszuführen:
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();
}
}
Sie sind jedoch abhängig von der Implementierung des JDBC-Treibers, wie viele Stapel Sie gleichzeitig ausführen können. Sie können sie beispielsweise alle 1000 Stapel ausführen:
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.
}
}
}
}
In Bezug auf Multithread-Umgebungen müssen Sie sich darüber keine Gedanken machen, wenn Sie die Verbindung und die Anweisung im kürzestmöglichen Umfang innerhalb desselben Methodenblocks gemäß der normalen JDBC-Redewendung mithilfe der Anweisung try-with-resources wie in Abbildung gezeigt erwerben und schließen über Schnipsel.
Wenn diese Stapel transaktional sind, möchten Sie die automatische Festschreibung der Verbindung deaktivieren und die Transaktion erst festschreiben, wenn alle Stapel abgeschlossen sind. Andernfalls kann es zu einer fehlerhaften Datenbank kommen, wenn die ersten Stapel erfolgreich waren und die späteren nicht.
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
ändert sich Ihre Anfrage nicht mit in der Schleife? Wenn sich diese Abfrage nicht für jede Iteration der Schleife ändert, warum erstellen Sie dannPreparedStatement
für jede Iteration eine neue (im ersten Codeausschnitt)? Gibt es einen Grund dafür?