Vous devez utiliser des insertions par lot.
- Créer une interface pour un référentiel personnalisé
SomeRepositoryCustom
public interface SomeRepositoryCustom {
void batchSave(List<Record> records);
}
- Créer une implémentation de
SomeRepositoryCustom
@Repository
class SomesRepositoryCustomImpl implements SomeRepositoryCustom {
private JdbcTemplate template;
@Autowired
public SomesRepositoryCustomImpl(JdbcTemplate template) {
this.template = template;
}
@Override
public void batchSave(List<Record> records) {
final String sql = "INSERT INTO RECORDS(column_a, column_b) VALUES (?, ?)";
template.execute(sql, (PreparedStatementCallback<Void>) ps -> {
for (Record record : records) {
ps.setString(1, record.getA());
ps.setString(2, record.getB());
ps.addBatch();
}
ps.executeBatch();
return null;
});
}
}
- Étendez votre
JpaRepository
avecSomeRepositoryCustom
@Repository
public interface SomeRepository extends JpaRepository, SomeRepositoryCustom {
}
pour économiser
someRepository.batchSave(records);
Remarques
Gardez à l'esprit que même si vous utilisez des insertions par lots, le pilote de base de données ne les utilisera pas. Par exemple, pour MySQL, il faut ajouter un paramètre rewriteBatchedStatements=true
à l'URL de la base de données. Il est donc préférable d'activer la journalisation SQL du pilote (et non Hibernate) pour tout vérifier. Peut également être utile pour déboguer le code du pilote.
Vous devrez décider de diviser les enregistrements par paquets dans la boucle
for (Record record : records) {
}
Un chauffeur peut le faire pour vous, vous n'en aurez donc pas besoin. Mais mieux vaut déboguer cette chose aussi.
P. S. N'utilisez pas var
partout.