spring 批量 SQL 查询没有准备好的语句

spring batch SQL queries without prepared statement

我读取行,从数据生成 SQL 查询,我需要写入数据库。我的过程没问题,但我无法通过编写器查询数据库。我认为我不能使用 PreparedStatement 因为除了生成的查询和那些查询更改之外我什么都没有,所以我认为它会生成一个错误(无效的批处理命令)。我怎样才能简单地把我的 SQL 放在这里?我可以像这样在 sql 方法中传递属性:.sql(query) 吗?顺便说一句,当我只需要 String 时,我切换到了 StringDTO。我没有其他方法可以将查询映射到 String class,什么是最合适的?创建一个对象只是为了在

中创建一个String似乎很糟糕

这是我的代码:

// tag::readerwriterprocessor[]
     @Bean
        public FlatFileItemReader<StringDTO> reader() {
            return new FlatFileItemReaderBuilder<StringDTO>()
                .name("StringDTOItemReader")
                .resource(new ClassPathResource("file.edi"))
                .delimited()
                .delimiter("\n")
                .names("query")
                .fieldSetMapper(new BeanWrapperFieldSetMapper<StringDTO>() {{
                    setTargetType(StringDTO.class);
                }})
                .build();
        }

    @Bean
    public StringDTOItemProcessor processor() {
        return new StringDTOItemProcessor();
    }

    @Bean
    public ListUnpackingItemWriter<StringDTO> listItemWriter(DataSource dataSource) {
        ListUnpackingItemWriter<StringDTO> writer = new ListUnpackingItemWriter<>();
        writer.setDelegate(writer(dataSource));
        return writer;
    }

    @Bean
    public ItemPreparedStatementSetter<StringDTO> itemPreparedStatementSetter() {
        return new StatementSetterTest();
    }

    public JdbcBatchItemWriter<StringDTO> writer(DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<StringDTO>()
                .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
                .sql(":query")
                .itemPreparedStatementSetter(itemPreparedStatementSetter())
                .dataSource(dataSource)
                .build();
    }
    // end::readerwriterprocessor[]

    // tag::jobstep[]
    @Bean
    public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
        return jobBuilderFactory.get("importUserJob")
            .incrementer(new RunIdIncrementer())
            .flow(step1)
            .end()
            .build();
    }

    @Bean
    public Step step1(ItemWriter<List<StringDTO>> writer) {
        return stepBuilderFactory.get("step1")
            .<StringDTO, List<StringDTO>> chunk(300)
            .reader(reader())
            .processor(processor())
            .writer(writer)
            .build();
    }
    // end::jobstep[]

建议的解决方案:

public class CustomWriter implements ItemWriter<String>{
    protected DataSource dataSource;

    public CustomWriter(DataSource dataSource){
        this.dataSource = dataSource;
    }
    
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void write(final List<? extends String> items) throws Exception {
        Statement statement = dataSource.getConnection().createStatement();
        Iterator<String> it = (Iterator<String>) items.iterator();
        while(it.hasNext()){
            String s = it.next();
            if(s.startsWith("INSERT INTO SQD_SQI2_TKO (change_date,TKO,K991_0992,F2801,F2801,F2802,F1803) VALUES (sysdate,2467"))
                System.out.println(s);
            statement.addBatch(s);
        }

        statement.executeBatch();
    }
}public class CustomWriter implements ItemWriter<String>{
    protected DataSource dataSource;

    public CustomWriter(DataSource dataSource){
        this.dataSource = dataSource;
    }
    
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void write(final List<? extends String> items) throws Exception {
        Statement statement = dataSource.getConnection().createStatement();
        Iterator<String> it = (Iterator<String>) items.iterator();
        while(it.hasNext()){
            String s = it.next();
            if(s.startsWith("INSERT INTO SQD_SQI2_TKO (change_date,TKO,K991_0992,F2801,F2801,F2802,F1803) VALUES (sysdate,2467"))
                System.out.println(s);
            statement.addBatch(s);
        }

        statement.executeBatch();
    }
}

与最初的问题无关,但这是我正在使用的映射器,因为我的输出只是一个 String,不需要映射到实际对象,也不需要映射到 sql输出

@Bean
    public FlatFileItemReader<String> reader() {
        return new FlatFileItemReaderBuilder<String>()
            .name("StringItemReader")
            .resource(new ClassPathResource("file.edi"))
            .delimited()
            .delimiter("\n")
            .names("query")
            .fieldSetMapper(new FieldSetMapper<String>() {
                @Override
                public String mapFieldSet(FieldSet arg0) throws BindException {
                    return arg0.readString(0);
                }
            })
            .build();
    }

my processor does return a list of queries - queries concern multiple tables

在这种情况下,您需要使用自定义项目编写器,因为 JdbcBatchItemWriter 接受单个查询。