java 在读取器、处理器和写入器处具有自定义处理和多个输入/输出数据类型的自定义Spring批处理流

a1o7rhls  于 2023-06-04  发布在  Java
关注(0)|答案(1)|浏览(233)

我有一个自定义的阅读器定义如下:

@Component
@StepScope
public class CustomItemReader implements ItemReader<String> {

  @Autowired
  BookingInfoRepository bookingInfoRepository;

  private List<String> bookingIds;

  @Override
  public String read() {
    if(Objects.isNull(bookingIds)){
      bookingIds = bookingInfoRepository.findDistinctId();
    }
    if (! bookingIds.isEmpty()) {
      return bookingIds.remove(0);
    }
    return null;
  }
}

因此,我使用从数据库返回的id设置变量bookingIds
然后,我有一些自定义处理器,它将与数据库对话并返回对象:

@Component
@StepScope
@Slf4j
public class CorrectionProcessor implements ItemProcessor<String, List<BookingInfo>> {

  @Autowired
  BookingInfoRepository bookingInfoRepository;

  @Override
  public List<BookingInfo> process(String bookingId) {
     
     List<BookingInfo> bookingInfoList = bookingInfoRepository.findById(bookingId);

     //do some processing, modify the objects in the list.

     return bookingInfoList;

  }

}

然后,我有一个自定义作家,如下所示:

@Component
@StepScope
public class CustomItemWriter implements ItemWriter<List<BookingInfo>> {

  @Autowired
  BookingInfoRepository bookingInfoRepository;

  @Override
  public void write(Chunk<? extends List<BookingInfo>> chunk) throws Exception {
    for(List<BookingInfo> bookingInfo: chunk){
      bookingInfoRepository(bookingInfo);
    }
  }
}

这是我的用例->

  1. Reader期望在主数据之外操作,该主数据是bookingId的列表。
  2. Reader将这个单独的bookingId传递给processorProcessor形成一个要返回给writer的自定义对象列表。请注意,处理器形成了list对象,而不是单个对象。
    1.作家需要采取的所有值列表中,并将它们保存到数据库。
    1.过程继续,直到所有bookingIds都被处理。
    我知道这可能不是利用 Spring 批次的理想方式。ReaderProcessor的步骤看起来可能很奇怪,但我需要坚持使用这个实现。我觉得我在上面提到的一个或多个步骤中做错了什么。我看到chunks每次都附加了数据。因此,相同的数据被多次插入。我如何将新添加的块写入数据库,而不是一次又一次地添加所有内容?我的其他配置是否正确?
jq6vz3qz

jq6vz3qz1#

@StepScope注解不适合您的用例。它导致bean在每一步执行之前都被示例化,并且您的局部变量丢失了内容。
使用@JobScope作为项目读取器。从其他两个bean中删除注解作为默认的单例示例就足够了。
请注意:要启用作业范围,请将@EnableBatchProcessing添加到其中一个配置类。

相关问题