Spring Batch - 从文件中读取查询并在数据库上执行

时间:2018-03-15 11:26:40

标签: spring spring-boot spring-batch

我知道我可以直接从step1读取文件,在将sql查询设置到阅读器之前的那一刻,但我希望将查询的过程与数据库读取分开。

这是我的工作配置。

@Configuration
public class BatchConfiguration {

    [...]

    @Bean
    @StepScope
    public JdbcCursorItemReader<Map<String, Object>> dynamicSqlItemReader() {
        JdbcCursorItemReader<Map<String, Object>> jir = new JdbcCursorItemReader<>();
        jir.setSql((String) contextHolder.getContext().get("fileContent"));
        jir.setDataSource(dataSource);
        jir.setRowMapper(new ColumnMapRowMapper());
        return jir;
    }

    private FlatFileItemReader<String> flatFileItemReader() {
        [...]
    }

    private ItemWriter<? super String> sysoItemWriter() {
        return (ItemWriter<String>) list -> {
            for (String element : list) {
                System.out.println(element);
            }
            contextHolder.getContext().put("fileContent", list.get(0));
        };
    }

    @Bean
    public ItemWriter<Map<String, Object>> customerItemWriter() {
        return list -> {
            for (Map<String, Object> stringObjectMap : list) {
                System.out.println(stringObjectMap);
            }
        };
    }

    @Bean
    public Step step0() {
        return stepBuilderFactory.get("step0")
                .<String, String>chunk(1)
                .reader(flatFileItemReader())
                .writer(sysoItemWriter())
                .build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .<Map<String, Object>, Map<String, Object>>chunk(10)
                .reader(dynamicSqlItemReader())
                .writer(customerItemWriter())
                .build();
    }


    @Bean
    public Job job() throws Exception {
        return jobBuilderFactory.get("job")
                .incrementer(new RunIdIncrementer())
                .start(step0())
                .next(step1())
                .build();
    }
}

这会引发java.lang.IllegalArgumentException: The SQL query must be provided,因为contextHolder.getContext().get("fileContent")在设置查询时仍为null

2 个答案:

答案 0 :(得分:0)

在第1步之前,您可以编写一个用于构建查询并将其放入上下文的tasklet,以便它保持独立,并且它也可用于step1。在此处查看有关tasklet的更多信息:Tasklet to delete a table in spring batch

答案 1 :(得分:0)

您没有正确使用创建的contextHolder,因为其值为null。

确保您将flatFileItemReader()中的数据直接放在contextHolder中作为地图,因为当您获得价值时,您正在使用contextholder.getContext()。由于它是一个简单的地图,而不是ApplicationContext,因此您使用的方法不存在。