有没有人知道如何在spring-batch(3.0.7)中处理返回实体列表的处理器的结果? 例如:
我有一个返回List的处理器
public class MyProcessor implements ItemProcessor < Long , List <Entity>> {
public List<Entity> process ( Long id )
}
现在所有后续处理器/编写器都需要在List&lt;实体&gt;。有没有办法将结果简化为Entity,以便给定步骤中的其他处理器可以处理单个实体?
唯一的方法是以某种方式使用编写器持久保存列表,然后创建一个可以从持久数据中读取的单独步骤。
提前致谢!
答案 0 :(得分:0)
除非您能提供令人信服的理由,否则没有理由向您的ItemWriter
发送列表清单。这不是ItemProcessor
打算使用的方式。相反,您应该创建/配置和ItemReader
以返回具有相关对象的一个对象。
例如,如果您正在从数据库中读取数据,则可以使用HibernateCursorItemReader
和类似这样的查询:
"from ParentEntity parent left join fetch parent.childrenEntities"
您的数据模型应该有一个父表,其中包含您当前正在传递给Long id
的{{1}},因此请利用这一优势。然后,读者将传回ItemProcessor
个对象,每个对象都包含与其一起出现的ParentEntity
个对象的集合。
答案 1 :(得分:0)
如您所知,spring-batch中的处理器可以使用复合处理器进行链接。在链中,您可以将处理类型从处理器更改为处理器,但当然两个&#34; neighbor&#34;处理器的输入和输出类型必须匹配。
但是,输出输出类型始终被视为一个项目。因此,如果处理器的输出类型是List,则此列表将被视为一个项目。因此,以下处理器需要具有InputType&#34; List&#34;,如果写入者遵循,则Writer需要具有List-of-List作为其写入方法的类型。 而且,处理器不能乘以其元素。每个输入元素只能有一个输出项。
基本上,拥有像
这样的链是没有错的Reader<Integer>
ProcessorA<Integer,List<Integer>>
ProcessorB<List<Integer>,List<Integer>>
Writer<List<Integer>> (which leads to a write-method write(List<List<Integer>> items)
根据具体情况,可能会有更好的解决方案。 您可以通过使用包装器和包装器编写器来缓解影响(例如可重用性),如下面的代码示例所示:
public class ListWrapperProcessor<I,O> implements ItemProcessor<List<I>, List<O>> {
ItemProcessor<I,O> delegate;
public void setDelegate(ItemProcessor<I,O> delegate) {
this.delegate = delegate;
}
public List<O> process(List<I> itemList) {
List<O> outputList = new ArrayList<>();
for (I item : itemList){
O outputItem = delegate.process(item);
if (outputItem!=null) {
outputList.add(outputItem);
}
}
if (outputList.isEmpty()) {
return null;
}
return outputList;
}
}
public class ListOfListItemWriter<T> implements InitializingBean, ItemStreamWriter<List<T>> {
private ItemStreamWriter<T> itemWriter;
@Override
public void write(List<? extends List<T>> listOfLists) throws Exception {
if (listOfLists.isEmpty()) {
return;
}
List<T> all = listOfLists.stream().flatMap(Collection::stream).collect(Collectors.toList());
itemWriter.write(all);
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(itemWriter, "The 'itemWriter' may not be null");
}
public void setItemWriter(ItemStreamWriter<T> itemWriter) {
this.itemWriter = itemWriter;
}
@Override
public void close() {
this.itemWriter.close();
}
@Override
public void open(ExecutionContext executionContext) {
this.itemWriter.open(executionContext);
}
@Override
public void update(ExecutionContext executionContext) {
this.itemWriter.update(executionContext);
}
}
使用这样的包装器,你仍然可以实现&#34; normal&#34;处理器和编写器然后使用这样的包装器来移动&#34; List&#34; - 处理它们。