我有一个自定义的阅读器定义如下:
@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);
}
}
}
这是我的用例->
Reader
期望在主数据之外操作,该主数据是bookingId的列表。- Reader将这个单独的
bookingId
传递给processor
,Processor形成一个要返回给writer的自定义对象列表。请注意,处理器形成了list
对象,而不是单个对象。
1.作家需要采取的所有值列表中,并将它们保存到数据库。
1.过程继续,直到所有bookingIds
都被处理。
我知道这可能不是利用 Spring 批次的理想方式。Reader
到Processor
的步骤看起来可能很奇怪,但我需要坚持使用这个实现。我觉得我在上面提到的一个或多个步骤中做错了什么。我看到chunks
每次都附加了数据。因此,相同的数据被多次插入。我如何将新添加的块写入数据库,而不是一次又一次地添加所有内容?我的其他配置是否正确?
1条答案
按热度按时间jq6vz3qz1#
@StepScope
注解不适合您的用例。它导致bean在每一步执行之前都被示例化,并且您的局部变量丢失了内容。使用
@JobScope
作为项目读取器。从其他两个bean中删除注解作为默认的单例示例就足够了。请注意:要启用作业范围,请将@EnableBatchProcessing添加到其中一个配置类。