我有一个现有的spring批处理项目,它根据启动期间的功能切换决定从MySQL或ArangoDB(NoSql数据库)读取数据并执行一些处理并再次写回MySQL / ArangoDB。
现在,MySQL的阅读器配置如下所示,
@Bean
@Primary
@StepScope
public HibernatePagingItemReader reader(
@Value("#{jobParameters[oldMetadataDefinitionId]}") Long oldMetadataDefinitionId) {
Map<String, Object> queryParameters = new HashMap<>();
queryParameters.put(Constants.OLD_METADATA_DEFINITION_ID, oldMetadataDefinitionId);
HibernatePagingItemReader<Long> reader = new HibernatePagingItemReader<>();
reader.setUseStatelessSession(false);
reader.setPageSize(250);
reader.setParameterValues(queryParameters);
reader.setSessionFactory(((HibernateEntityManagerFactory) entityManagerFactory.getObject()).getSessionFactory());
return reader;
}
我还有另一个像下面这样的arango读者,
@Bean
@StepScope
public ListItemReader arangoReader(
@Value("#{jobParameters[oldMetadataDefinitionId]}") Long oldMetadataDefinitionId) {
List<InstanceDTO> instanceList = new ArrayList<InstanceDTO>();
PersistenceService arangoPersistence = arangoConfiguration
.getPersistenceService());
List<Long> instanceIds = arangoPersistence.getDefinitionInstanceIds(oldMetadataDefinitionId);
instanceIds.forEach((instanceId) ->
{
InstanceDTO instanceDto = new InstanceDTO();
instanceDto.setDefinitionID(oldMetadataDefinitionId);
instanceDto.setInstanceID(instanceId);
instanceList.add(instanceDto);
});
return new ListItemReader(instanceList);
}
我的步骤配置如下,
@Bean
@SuppressWarnings("unchecked")
public Step InstanceMergeStep(ListItemReader arangoReader, ItemWriter<MetadataInstanceDTO> arangoWriter,
ItemReader<Long> mysqlReader, ItemWriter<Long> mysqlWriter) {
Step step = null;
if (arangoUsage) {
step = steps.get("arangoInstanceMergeStep")
.<Long, Long>chunk(1)
.reader(arangoReader)
.writer(arangoWriter)
.faultTolerant()
.skip(Exception.class)
.skipLimit(10)
.taskExecutor(stepTaskExecutor())
.build();
((TaskletStep) step).registerChunkListener(chunkListener);
}
else {
step = steps.get("mysqlInstanceMergeStep")
.<Long, Long>chunk(1)
.reader(mysqlReader)
.writer(mysqlWriter)
.faultTolerant()
.skip(Exception.class)
.skipLimit(failedSkipLimit)
.taskExecutor(stepTaskExecutor())
.build();
((TaskletStep) step).registerChunkListener(chunkListener);
}
return step;
}
MySQL阅读器通过HibernatePagingItemReader提供分页支持,这样它就可以处理数百万个项目而不会出现任何内存问题。
我想为arango阅读器实现相同的分页支持,每次迭代只能获取250个文档,如何修改arango阅读器代码来实现这一目标?
答案 0 :(得分:0)
首先,ListItemReader的文档说 - 对测试有用所以不要将它用于制作。从所有读者bean而不是实际的具体类型返回ItemReader
。
话虽如此,Spring Batch API或Spring Data似乎并不支持Arango DB。我能找到的最近的是this
(之前我没有和Arango DB合作过)。
所以在我看来,你必须编写自己的自定义arango阅读器,通过实现抽象类来实现分页 - org.springframework.batch.item.database.AbstractPagingItemReader
如果通过扩展上面的类不可行,你可能必须从头开始实现所有内容。 Spring Batch API中的所有分页读者都扩展了这个抽象类,包括HibernatePagingItemReader
。
另外,请记住arango记录集应该有某种排序来实现分页,这样我们就可以区分page-0&amp;第-1页等(类似于ORDER BY
子句,BETWEEN
运算符&amp; less,大于SQL中的运算符等。另外FETCH FIRST XXX ROWS
OR LIMIT
子句类似于也需要)。
由您自己实施并不是一项非常艰巨的任务,因为您必须计算总可能的项目,订购它们然后分成页面并一次只获取一页。
查看API的实现,例如 - HibernatePagingItemReader
等,以获取想法。
希望它有所帮助!!