Spring 批处理 - 使用 SingleItemPeekableItemReader 从平面文件制作伪数据库

Spring Batch - using SingleItemPeekableItemReader to make a pseudo-DB from a flat file

我需要使用 Spring 从多个平面文件读取、处理然后将数据写回平面文件的批处理重写现有应用程序。

第一个输入文件包含密钥数据,其余输入文件可能包含也可能不包含第一个文件中密钥的交易数据。我在想,使用一个FlatFileItemReader获取关键数据,并在处理器中使用一系列SingleItemPeekableItemReader来构建交易数据并将其添加到中是有意义的Data 对象(使用可窥视的 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)

这可能吗?我尝试将 SingleItemPeekableItemReader 注入到 ItemProcessor 中,但是当处理器尝试进行 peek 时,它只会得到一个 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();
      }