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

时间:2016-06-16 18:01:23

标签: java spring-batch

我们的处理器会将List<?>(有效地传递List<List<?>>)返回到ItemWriter

现在,我们发现JdbcBatchItemWriter没有编程来处理item instanceof List。我们还观察到处理项目实例List;我们需要编写自定义ItemSqlParameterSourceProvider

但令人遗憾的是,它返回的SqlParameterSource只能处理一个item并且再次无法处理List

那么,有人可以帮助我们了解如何处理JdbcBatchItemWriter中的列表列表吗?

2 个答案:

答案 0 :(得分:9)

通常,设计模式是:

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

如果您的处理器正在返回List<Object>,那么您需要您的Writer期待List<List<Object>>

您可以将JdbcBatchItemWriter作为委托包装在ItemWriter中,如下所示:

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;
    }

}

答案 1 :(得分:1)

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())));
    }

}

只需将自定义行聚合器添加到上述解决方案中,这有助于使用FlatFileItemWriter<List<T>>将内容写入文件。您可以将T替换为实际的类名,以避免在调用toString()方法时出现编译错误。