【问题标题】:Spring Batch - Read query from file and execute it on databaseSpring Batch - 从文件中读取查询并在数据库上执行
【发布时间】:2018-03-15 11:26:39
【问题描述】:

我知道我可以直接从第 1 步读取文件,在将 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

【问题讨论】:

  • 数据库查询在做什么?
  • 我不知道先验:sql 查询的路径将是一个批处理参数。但基本上他们是select
  • 您使用的是哪个 contextHolder?
  • 这是我的一个包含 Map 的 bean。

标签: spring spring-boot spring-batch


【解决方案1】:

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

【讨论】:

  • 我也尝试过使用tasklet,但问题仍然存在。 @Bean public Step step0() { return stepBuilderFactory.get("step0") .tasklet((stepContribution, chunkContext) -&gt; { File f = new File("D:\\query.sql"); contextHolder.getContext().put("fileContent", FileUtils.readFileToString(f, "UTF-8")); return RepeatStatus.FINISHED; }) .build(); }
【解决方案2】:

你没有正确使用你创建的contextHolder,这就是为什么那里的值是空的。

确保您将数据直接作为映射放入contextHolder 中的flatFileItemReader(),因为当您获得价值时,您使用的是contextholder.getContext()。因为是简单的地图,不是ApplicationContext,所以你使用的方法不存在。

【讨论】:

    猜你喜欢
    • 2020-08-15
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    相关资源
    最近更新 更多