我在Spring Batch中有一个要求,我有一个文件,其中有数千条记录按排序顺序排列。关键字段是产品代码。 该文件可能有多个相同产品代码的记录。要求是我必须对具有相同产品代码的记录进行分组 product集合中的代码(即List)然后将它们发送到一个方法,即validateProductCodes(List prodCodeList)。 我正在寻找最好的方法。我想到的方法是读取处理器中的每条记录,然后构建一个集合 处理器中相同产品代码的记录。如果处理器中的任何一点,如果记录中的产品代码不同,则意味着 productCode分组已完成,并且可以使用相同的产品代码为该组记录调用validateProductCodes()。我也使用Step.So 这不是自动意味着进程是多线程的吗?含义具有相同productCode的记录组将以多线程方式处理。请注意。
由于
答案 0 :(得分:1)
您的问题中有两个问题:首先,您想知道如何将这些项目组合在一起以及如何处理这些项目。
为了对它们进行分组,您可以像Luca建议的那样创建一个组阅读器,或者类似:
public class GroupReader<I> implements ItemReader<List<I>>{
private SingleItemPeekableItemReader<I> reader;
private ItemReader<I> peekReaderDelegate;
public void setReader(ItemReader<I> reader) {
peekReaderDelegate = reader;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(peekReaderDelegate, "The 'itemReader' may not be null");
this.reader= new SingleItemPeekableItemReader<I>();
this.reader.setDelegate(delegateReader);
}
@Override
public List<I> read() throws Exception {
State state = State.NEW;
List<I> group = null;
I item = null;
while (state != State.COMPLETE) {
item = reader.read();
switch (state) {
case NEW: {
if (item == null) {
// end reached
state = State.COMPLETE;
break;
}
group = new ArrayList<I>();
group.add(item);
state = State.READING;
I nextItem = reader.peek();
if (isItAKeyChange(item, nextItem)) {
state = State.COMPLETE;
}
break;
}
case READING: {
group.add(item);
// peek and check if there the peeked entry has a new date
I nextItem = peekEntry();
if (isItAKeyChange(item, nextItem)) {
state = State.COMPLETE;
}
break;
}
default: {
throw new org.springframework.expression.ParseException(groupCounter, "ParsingError: Reader is in an invalid state");
}
}
}
return group;
}
}
对于每个键,此阅读器将返回一个列表,其中包含与此键匹配的所有元素。因此,分组直接在读者中完成。 正如您所描述的那样,您无法使用处理器执行此操作。
关于多线程的第二个问题。 现在,使用步骤并不一定意味着,步骤是用多个线程处理的。
为此,您需要设置AsyncTaskExecutor,并且必须设置限制。
但是,如果你这样做,你的读者必须是线程安全的,否则你的分组不会起作用。你可以通过简单地将上面的read方法定义为synchronized来实现。
另一种方法是编写一个小的SynchronizedWrapperReader,如本问题所示:Parellel Processing Spring Batch StaxEventItemReader
请注意,根据您要写入的目标,您可能还需要同步编写器,并在必要时重新排序结果。