【发布时间】:2021-08-12 16:09:09
【问题描述】:
我创建了一个通用 Spring Batch 作业,用于处理数据并将其存储到 CSV 中。我需要一些来自阅读器的数据传递给我正在尝试使用 JobExecution 执行的编写器。然而令人惊讶的是,代码似乎首先调用 getWriter() 而不是 getReader() 函数。 我的配置如下。有人可以解释为什么会发生这种情况,以及是否有其他方法可以将数据从读取器传递到写入器。
@Bean
@StepScope
public ItemReader<Map<String, Object>> getDataReader() throws Exception {
return springBatchReader.getReader();
}
@Bean
@StepScope
public FlatFileItemWriter<Map<String, Object>> getDataWriter() throws Exception {
return (FlatFileItemWriter<Map<String, Object>>) springBatchWriter.getWriter();
}
@Bean
public Job SpringBatchJob(Step generateReport) throws Exception {
return jobBuilderFactory.get("SpringBatchJob" + System.currentTimeMillis())
.preventRestart()
.incrementer(new RunIdIncrementer())
.flow(generateReport)
.end()
.build();
}
@Bean
public Step generateReport() throws Exception {
return stepBuilderFactory.get("generateReport").<Map<String, Object>, Map<String, Object>>chunk(batchSize)
.reader(getDataReader()).writer(getDataWriter()).build();
}
我想从 Reader 传递给 Writer 的数据是 CSV 的列名。 由于我的阅读器运行可变 SQL 查询(传递 SQL 查询以作为命令行参数运行),因此结果集/列不是静态的,而是根据给定的查询而变化。在 setHeaderCallback 中为编写者提供要为特定执行写入的列名是从 Reader 向 Writer 发送数据的基本原理。
Reader 简单地运行给定的查询并将数据放入 Map
编写器代码如下:
public FlatFileItemWriter<Map<String, Object>> getWriter() throws Exception {
String reportName = getReportName();
saveToContext(reportName, reportPath);
FileSystemResource resource = new FileSystemResource(String.join(File.separator, reportPath, getReportName()));
FlatFileItemWriter<Map<String, Object>> flatFileItemWriter = new FlatFileItemWriter<>();
flatFileItemWriter.setResource(resource);
//NEED HELP HERE..HOW TO SET THE HEADER TO BE THE KEYS OF THE MAP
//flatFileItemWriter.setHeaderCallback();
flatFileItemWriter.setLineAggregator(new DelimitedLineAggregator<Map<String, Object>>() {
{
setDelimiter(delimiter);
setFieldExtractor(
new PassThroughFieldExtractor<>()
);
}
});
flatFileItemWriter.afterPropertiesSet();
return flatFileItemWriter;
}
【问题讨论】:
标签: java spring spring-batch batch-processing