Você tem que usar inserções em lote.
- Criar uma interface para um repositório personalizado
SomeRepositoryCustom
public interface SomeRepositoryCustom {
void batchSave(List<Record> records);
}
- Crie uma implementação 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;
});
}
}
- Estenda seu
JpaRepository
comSomeRepositoryCustom
@Repository
public interface SomeRepository extends JpaRepository, SomeRepositoryCustom {
}
salvar
someRepository.batchSave(records);
Observações
Lembre-se de que, se você estiver usando inserções em lote, o driver do banco de dados não as usará. Por exemplo, para MySQL, é necessário adicionar um parâmetro
rewriteBatchedStatements=true
para a URL do banco de dados. Portanto, é melhor habilitar o log do SQL do driver (não o Hibernate) para verificar tudo. Também pode ser útil para depurar o código do driver. Você precisará tomar uma decisão sobre a divisão de registros por pacotes no loop
for (Record record : records) {
}
Um motorista pode fazer isso por você, então você não precisará dele. Mas é melhor depurar essa coisa também.
P.S. Não use
var
em toda parte.