java - Spring Batch - 使用 SingleItemPeekableItemReader 从平面文件创建伪数据库
问题描述
我需要使用 Spring Batch 重写现有应用程序,该应用程序从多个平面文件中读取,进行处理,然后将数据写回平面文件。
第一个输入文件包含密钥数据,其余输入文件可能包含也可能不包含来自第一个文件的密钥的交易数据。我在想使用 aFlatFileItemReader
来获取关键数据是有意义的,并在处理器中使用一系列SingleItemPeekableItemReader
来构建事务数据并将其添加到Data对象中(使用 peekable reader,因为关键可能不在额外的文件 - 是的,这些文件是预先排序的)。
伪代码
while(<more data>) {
while (data.getKey() == peekablePeek.getKey()) {
data.addTransaction(peekable.read());
// repeat for each transaction file
}
// do regular processing for transactions (which will update <data> object fields based)
这甚至可能吗?我尝试将 aSingleItemPeekableItemReader
注入其中,ItemProcessor
但是Reader not Open
当处理器尝试进行窥视时,它只会出现异常。
任何想法将不胜感激。
解决方案
需要发生的是,我需要确保文件在命中处理器之前已打开。我所做的是设置两个 Tasklet - 一个用于打开文件,一个用于关闭文件,然后根据需要将它们添加到作业配置中(Open
在常规步骤之前和常规步骤Close
之后)。
小任务:
public class OpenSubFileTask implements Tasklet {
@Autowired
SingleItemPeekableItemReader<Data> readerPeek;
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception
{
readerPeek.open(contribution.getStepExecution().getExecutionContext());
return RepeatStatus.FINISHED;
}
public class CloseSubFileTask implements Tasklet {
@Autowired
SingleItemPeekableItemReader<Data> readerPeek;
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception
{
readerPeek.close();
return RepeatStatus.FINISHED;
}
}
作业配置:
@Bean
public Job importUserJob(JobNotificationListener listener,
Step stepOpen, Step stepClose, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.start(stepOpen)
.next(step1)
.next(stepClose)
.build();
}