12

我做了一些搜索,但找不到任何示例/示例。

我需要读取一个表(输入)中的地理坐标,并对其进行处理以生成与坐标相关联的 POI。因此,一个地理坐标将导致一个或多个 POI 需要插入到另一个表(输出)中。

我目前正在使用 JdbcCursorItemReader 和 JdbcBatchItemWriter 来读取一项/记录并写入一项/记录。还有一个 ItemProcessor 可以为给定的地理坐标生成 POI。

自定义 JdbcBatchItemWriter 是否可以帮助我实现这一目标?

有任何想法吗?TIA。

4

4 回答 4

10

您真正要寻找的是一种拆分器模式:

在此处输入图像描述

这是它在Spring Integration中的定义方式:

拆分器是一种消息端点,其职责是从其输入通道接受消息,将该消息拆分为多个消息,然后将每个消息发送到其输出通道。这通常用于将“复合”有效负载对象划分为一组包含细分有效负载的消息。

配置极其简单:

<channel id="inputChannel"/>

<splitter id="splitter" 
  ref="splitterBean" 
  method="split" 
  input-channel="inputChannel" 
  output-channel="outputChannel" />

<channel id="outputChannel"/>

<beans:bean id="splitterBean" class="sample.PojoSplitter"/>

或者您可以使用注释:

@Splitter
List<LineItem> extractItems(Order order) {
    return order.getItems()
}

JdbcBatchItemWriter如果感觉更简单,您当然可以自己编写。然而,Spring Integration 已经为您做到了。

您可以使用Spring Integration JDBC Support => jdbc:inbound-channel-adapter/jdbc:outbound-channel-adapter和上面的拆分器来实现您想要的和..简单。

于 2011-10-26T02:01:38.927 回答
6

如果您只想将项目分散到不同的编写器(读取重复输出),您可以使用现有的CompositeItemWriter

但我不确定您的处理器是否会产生不同的项目类型,或者您是否想将一种复杂项目类型的内容传播给多个作者,对于这些情况,您可以使用稍微更改的版本来解决多行记录作者问题

public class MultiOutputItemWriter implements ItemWriter<Object> {

private JdbcBatchItemWriter<ClassFoo> delegateFoo;
private JdbcBatchItemWriter<ClassBar> delegateBar;

public void write(List<? extends Object> items) throws Exception {
       // if you have different types of items
       // check Object Class
       // add to new List<Classfoo>
       // call delegate e.g. delegateFoo.write(List with ClassFoo);
       //
       // or if you have complex objects
       // same procedure as above, but with
       // add to new List<Classfoo> with item.getClassFoo
 }
}

如果您使用 FlatFileItemWriter,请不要忘记将代表注册为 ItemStreams(因此 Spring Batch 将为您打开/关闭它们)

于 2011-10-25T20:00:40.753 回答
1

我通过扩展 Writer 类(在我的例子中为 HibernateItemWriter)来做到这一点。我看到一个答案描述了如何使用“分离器”。如果有人有一个工作示例,说明在使用 spring-boot-starter-parent 的环境中如何工作,我很乐意看到它。对于我正在做的事情(从单个记录创建一个列表),如果 Spring 提供了一个处理列表列表的写入方法,那将会容易得多。

以下是我如何扩展 Writer 以处理读取/处理的每​​一行的多次写入:Spring-Batch Multi-line record Item Writer with variable number of lines per record

于 2015-01-05T23:07:12.127 回答
0

我有一个类似的案例,我可以使用以下可重用代码来解决它:

@Slf4j
public class ListItemWriter<T> implements ItemWriter<List<T>> {

  private ItemWriter<T> delegate;

  @Setter private int chunkSize = 0;

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

  @Override
  public void write(List<? extends List<T>> items) throws Exception {
    if (chunkSize == 0) {
      chunkSize = items.size();
    }
    List<T> allItems = items.stream().flatMap(Collection::stream).collect(Collectors.toList());
    log.info("writing {} items", allItems.size());
    List<List<T>> partitions = ListUtils.partition(allItems, chunkSize);
    for (List<T> partition : partitions) {
      delegate.write(partition);
    }
  }
}

读者:A
处理器:A -> List<B>
作家:新 ListItemWriter(ItemWriterForB)

于 2022-01-31T11:53:56.973 回答