PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Qual é a maneira mais eficiente de persistir milhares de entidades?


Você tem que usar inserções em lote.
  1. Criar uma interface para um repositório personalizado SomeRepositoryCustom
public interface SomeRepositoryCustom {

    void batchSave(List<Record> records);

}
  1. 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;
        });
    }

}
  1. Estenda seu JpaRepository com SomeRepositoryCustom
@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.