简体   繁体   English

Spring Batch - 使用带有列表列表的 ItemWriter

[英]Spring Batch - Using an ItemWriter with List of Lists

Our processor returns a List<?> (effectively passing a List<List<?>> ) to our ItemWriter .我们的处理器返回一个List<?> (有效地传递一个List<List<?>> )给我们的ItemWriter

Now, we observed that the JdbcBatchItemWriter is not programmed to handle item instanceof List .现在,我们观察到JdbcBatchItemWriter没有被编程来处理item instanceof List We also observed to process item instanceof List ;我们还观察到处理项目 instanceof List we need to write a custom ItemSqlParameterSourceProvider .我们需要编写一个自定义的ItemSqlParameterSourceProvider

But the sad part is that it returns SqlParameterSource which can handle only one item and again not capable of handling a List .但可悲的是它返回SqlParameterSource ,它只能处理一个item并且再次不能处理List

So, can someone help us understand how to handle list of lists in the JdbcBatchItemWriter ?那么,有人可以帮助我们了解如何处理JdbcBatchItemWriter中的列表列表吗?

Typically, the design pattern is:通常,设计模式是:

Reader -> reads something, returns ReadItem
Processor -> ingests ReadItem, returns ProcessedItem
Writer -> ingests List<ProcessedItem>

If your processor is returning List<Object> , then you need your Writer to expect List<List<Object>> .如果您的处理器返回List<Object> ,那么您需要您的 Writer 期待List<List<Object>>

You could do this by wrapping your JdbcBatchItemWriter as a delegate in an ItemWriter that looks something like this:您可以通过将JdbcBatchItemWriter作为委托包装在JdbcBatchItemWriter来做到这一点,如下所示:

public class ListUnpackingItemWriter<T> implements ItemWriter<List<T>>, ItemStream, InitializingBean {

    private ItemWriter<T> delegate;

    @Override
    public void write(final List<? extends List<T>> lists) throws Exception {
        final List<T> consolidatedList = new ArrayList<>();
        for (final List<T> list : lists) {
            consolidatedList.addAll(list);
        }
        delegate.write(consolidatedList);
    }

    @Override
    public void afterPropertiesSet() {
        Assert.notNull(delegate, "You must set a delegate!");
    }

    @Override
    public void open(ExecutionContext executionContext) {
        if (delegate instanceof ItemStream) {
            ((ItemStream) delegate).open(executionContext);
        }
    }

    @Override
    public void update(ExecutionContext executionContext) {
        if (delegate instanceof ItemStream) {
            ((ItemStream) delegate).update(executionContext);
        }
    }

    @Override
    public void close() {
        if (delegate instanceof ItemStream) {
            ((ItemStream) delegate).close();
        }
    }

    public void setDelegate(ItemWriter<T> delegate) {
        this.delegate = delegate;
    }

}
public class ListUnpackingItemWriter<T> implements FlatFileItemWriter<List<T>>, ItemStream, InitializingBean {

    @Override
    public void afterPropertiesSet() {
        setLineAggregator(item -> String.join("\n", item.stream().map(T::toString).collect(Collectors.toList())));
    }

}

Just added a custom line aggregator to the above solution, this helps in writing the content to a file by using FlatFileItemWriter<List<T>> .刚刚向上述解决方案添加了一个自定义行聚合器,这有助于使用FlatFileItemWriter<List<T>>将内容写入文件。 You can replace T with actual class name to avoid compilation error while calling toString() method.您可以用实际的类名替换T以避免在调用toString()方法时出现编译错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM