【问题标题】:I cannot insert to the mysql database with spring batch我无法使用 Spring Batch 插入 mysql 数据库
【发布时间】:2019-11-15 01:22:09
【问题描述】:

我正在尝试将信息从 excel 文件插入到 mysql,我正在使用 springbatch excel 的扩展名来读取文件,但是当尝试插入 mysql 时,它显然给出了错误,它没有发送我共享的信息batch.config

@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {

    @Bean
    @Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
    public Pagare pagare() {
        return new Pagare();
    }

    @Bean
    @Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
    public ItemProcessor<Pagare, Pagare> itemProcessor() {
        return new PagareItemProcessor();
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        // dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/pagare");
        dataSource.setUsername("root");
        dataSource.setPassword("");
        ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
        databasePopulator.addScript(new ClassPathResource("org/springframework/batch/core/schema-drop-mysql.sql"));
        databasePopulator.addScript(new ClassPathResource("org/springframework/batch/core/schema-mysql.sql"));
        DatabasePopulatorUtils.execute(databasePopulator, dataSource);
        return dataSource;
    }

    @Bean
    public BeanWrapperFieldSetMapper<Pagare> beanWrapperFieldSetMapper() {
        BeanWrapperFieldSetMapper<Pagare> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
        fieldSetMapper.setPrototypeBeanName("pagare");
        return fieldSetMapper;
    }

    @Bean
    ItemReader<Pagare> pagareReader() {
        PoiItemReader<Pagare> reader = new PoiItemReader<>();
        reader.setResource(new ClassPathResource("pagares.xlsx"));
        reader.setRowMapper(excelRowMapper());
        return reader;
    }

    private RowMapper<Pagare> excelRowMapper() {
        return new RowMapperImpl();
    }

    @Bean
    public BeanPropertyItemSqlParameterSourceProvider<Pagare> beanPropertyItemSqlParameterSourceProvider() {
        return new BeanPropertyItemSqlParameterSourceProvider<>();
    }

    @Bean
    public ItemWriter<Pagare> JdbcBatchItemWriter(DataSource dataSource,
                                                  BeanPropertyItemSqlParameterSourceProvider<Pagare> sqlParameterSourceProvider) {
        JdbcBatchItemWriter<Pagare> jdbcBatchItemWriter = new JdbcBatchItemWriter<>();
        jdbcBatchItemWriter.setDataSource(dataSource);
        jdbcBatchItemWriter.setItemSqlParameterSourceProvider(sqlParameterSourceProvider);
        jdbcBatchItemWriter.setSql("insert into pagare(operacion,id,contrato,tipo,analista,fechaCargaDocumento,estadoOperacion,fechaCambioEstado) values (:operacion, :id, :contrato, :tipo, :analista, :fechaCargaDocumento, :estadoOperacion, :fechaCambioEstado)");

        return jdbcBatchItemWriter;
    }

    @Bean
    public Job jobCsvMysql(JobBuilderFactory jobBuilderFactory, Step step) {
        return jobBuilderFactory.get("jobCsvMysql").incrementer(new RunIdIncrementer()).flow(step).end().build();
    }

    @Bean
    public Step step1(StepBuilderFactory stepBuilderFactory,
                      ItemReader<Pagare> pagareReader, ItemWriter<Pagare> writer, ItemProcessor<Pagare, Pagare> processor) {
        return stepBuilderFactory.get("step1").<Pagare, Pagare>chunk(6)
                .reader(pagareReader).processor(processor).writer(writer).build();
    }

}

org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [插入 pagare(test1,id,test3,test4,test5,test6,test7,test8) 值 (?, ?, ?, ?, ?, ?, ?, ?)];列“id”不能为空;嵌套异常是 java.sql.BatchUpdateException: Column 'test2' cannot be null

我尝试更改我的 bd 和我的模型的值,我得到相同的结果,我使用 BeanPropertyItemSqlParameterSourceProvider 的原因是因为我插入的参数等于我在下面留下的模型的属性的参数

public class Pagare {
    private String operacion;
    private String rut;
    private String contrato;
    private String tipo;
    private String analista;
    private String fechaCargaDocumento;
    private String estadoOperacion;
    private String fechaCambioEstado;




    public String getOperacion() {
        return operacion;
    }

    public void setOperacion(String operacion) {
        this.operacion = operacion;
    }

    public String getTipo() {
        return tipo;
    }

    public void setTipo(String tipo) {
        this.tipo = tipo;
    }

    public String getAnalista() {
        return analista;
    }

    public void setAnalista(String analista) {
        this.analista = analista;
    }

    public String getFechaCargaDocumento() {
        return fechaCargaDocumento;
    }

    public void setFechaCargaDocumento(String fechaCargaDocumento) {
        this.fechaCargaDocumento = fechaCargaDocumento;
    }

    public String getEstadoOperacion() {
        return estadoOperacion;
    }

    public void setEstadoOperacion(String estadoOperacion) {
        this.estadoOperacion = estadoOperacion;
    }

    public String getFechaCambioEstado() {
        return fechaCambioEstado;
    }

    public void setFechaCambioEstado(String fechaCambioEstado) {
        this.fechaCambioEstado = fechaCambioEstado;
    }

    public String getRut() {
        return rut;
    }

    public void setRut(String rut) {
        this.rut = rut;
    }

    public String getContrato() {
        return contrato;
    }

    public void setContrato(String contrato) {
        this.contrato = contrato;
    }


    @Override
    public String toString() {
        return "Pagare [operacion=" + operacion + ", rut=" + rut + ", contrato=" + contrato + ",tipo=" + tipo + ",analista=" + analista + ",fechaCargaDocumento=" + fechaCargaDocumento + ",estadoOperacion=" + estadoOperacion + ",fechaCambioEstado=" + fechaCambioEstado + "]";
    }

我的物品处理器是这​​个


    private static final Logger LOG = LoggerFactory.getLogger(PagareItemProcessor.class);

    @Override
    public Pagare process(Pagare pagare) throws Exception {

        LOG.info("Processing " + pagare);

        final String initCapAnalista = pagare.getAnalista().substring(0, 1).toUpperCase()
                + pagare.getAnalista().substring(1);
        final String initCapTipo = pagare.getTipo().substring(0, 1).toUpperCase()
                + pagare.getTipo().substring(1);
        Pagare transformedPagare = new Pagare();
        transformedPagare.setOperacion(pagare.getOperacion());
        transformedPagare.setAnalista(initCapAnalista);
        transformedPagare.setTipo(initCapTipo);
        return transformedPagare;


    }

    }

读取文件和错误时控制台的这张图片

【问题讨论】:

  • 您的Pagare 项目中的test2 看起来是null,并且表中的相应列不可为空。因此,要么将列更改为可为空,要么确保在写入项目之前对其进行验证(这可以使用 BeanValidatingItemProcessor 来完成,例如,请参阅 docs.spring.io/spring-batch/docs/4.2.x/reference/html/…
  • 如果我可以在excel文件控制台中读取信息,是否有效?我将编辑我上传捕获的帖子

标签: mysql spring spring-batch


【解决方案1】:

由于您在 INSERT 语句中使用命名参数,因此您需要将 NamedParameterJdbcTemplate 注入到您的编写器中。还要确保参数名称与 Pagare 类型的属性名称匹配(您没有共享)。

【讨论】:

  • 我不使用 NamedParameterJdbcTemplate 我仍然得到同样的错误添加我的类模型
  • 您提供的信息不一致。在您的代码中,INSERT 语句读取为insert into pagare(operacion,id,contrato,tipo,analista,fechaCargaDocumento,estadoOperacion,fechaCambioEstado) values (...),但在错误消息中读取为insert into pagare(test1,id,test3,test4,test5,test6,test7,test8) values (?, ?, ?, ?, ?, ?, ?, ?)。您能否也分享来自您的schema-mysql.sql 的 CREATE TABLE 语句。我注意到的另一件事是,INSERT 语句引用了一个命名查询参数:id,但Pagare 有一个字段rut
猜你喜欢
  • 2019-10-22
  • 1970-01-01
  • 2022-06-21
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
  • 2018-10-14
  • 2018-02-22
  • 2019-10-06
相关资源
最近更新 更多