sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cuál es la forma más eficiente de persistir miles de entidades?

Tienes que usar inserciones por lotes.

  1. Cree una interfaz para un repositorio personalizado SomeRepositoryCustom
public interface SomeRepositoryCustom {

    void batchSave(List<Record> records);

}
  1. Cree una implementación 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. Amplía tu JpaRepository con SomeRepositoryCustom
@Repository
public interface SomeRepository extends JpaRepository, SomeRepositoryCustom {

}

guardar

someRepository.batchSave(records);

Notas

Tenga en cuenta que, incluso si está utilizando inserciones por lotes, el controlador de la base de datos no las utilizará. Por ejemplo, para MySQL, es necesario agregar un parámetro rewriteBatchedStatements=true a la URL de la base de datos. Es mejor habilitar el registro SQL del controlador (no Hibernate) para verificar todo. También puede ser útil para depurar el código del controlador.

Deberá tomar una decisión sobre la división de registros por paquetes en el bucle

    for (Record record : records) { 

    }

Un conductor puede hacerlo por usted, por lo que no lo necesitará. Pero es mejor depurar esto también.

P. D. No use var en todas partes.