java - 将单个参数而不是列表传递给 ItemWriter 接口(interface)的 Write() 方法

标签 java spring spring-batch batch-processing

我正在使用 Spring Batch 从 CSV 文件读取数据,然后将其保存到数据库中。到目前为止,一切都很好,除了我的输入文件包含混合数据(多个表的多个列)。

我创建了一个类CsvFileLine它将包含文件的整行,并实现接口(interface) ItemReader<CsvFileLine>然后实现接口(interface)ItemProcessor<List<CsvFileLine>, ProcessorResult>我将向其传递 CsvFileLine 的列表它返回 ProcessorResult 类型的对象我也创建了它并包含 3 ArrayList<>ClassA , ClassBClassC .

我现在的问题是当我需要实现接口(interface) ItemWriter<ProcessorResult> 时方法write(List<? extends T> items)需要一个扩展其他类的项目列表,而我打算传递一个包含 4 个 ArrayList 和必要数据的 ProcessorResult 对象。

有人可以建议我如何处理这个案子吗?有没有办法只传递 1 个参数?

最佳答案

感谢您的澄清。如果我理解正确的话,您是说文件中的每一行都包含 ClassA 的每个实例。 , ClassB ,和ClassC 。对于本示例,我将假设是这样,但即使关系不同,解决方案也会类似。

设置 Spring Batch 作业的关键是考虑“项目”的构成以及您希望它发生什么。您还需要了解框架如何将每个接口(interface)的输出传递为下一个接口(interface)的输入。 ( Spring 很好documentation)。 ItemReader的返回类型作为单例传递到 ItemProcessor 。所以在你的情况下,ItemProcessor实际上应该是ItemProcessor<CsvFileLine, ProcessorResult>而不是 ItemProcessor<List<CsvFileLine>, ProcessorResult>你有的。来自 ItemProcessor 的切换至ItemWriter有点棘手。 ItemWriter实现应采取 List ItemProcessor 的返回类型。 ItemWriter需要 List因为 Spring Batch 组 ItemProcessor输出一起形成交易。就您而言,您可以有 ItemWriter<List<ProcessorResult>>

有了这个基础,我们就可以改变ProcessorResult的结构了然后作者很容易实现。而不是ProcessorResult包含文件中的所有数据,它将仅包含一行数据:

public class ProcessorResult {
    private ClassA classA;
    private ClassB classB;
    private ClassC classC;
    // Constructor and getters omitted for brevity
}

ItemProcessor需要一个CsvFileLine并将其转换为 ProcessorResult :

public class ExampleProcessor implements ItemProcessor<CsvFileLine, ProcessorResult> {

  public ProcessorResult process(CsvFileLine line){
    // mapping into ProcessorResult goes here
  }

ItemWriter需要 List这些并需要将它们保存到数据库中。它可能看起来像这样:

public class ExampleItemWriter implements ItemWriter<List<ProcessorResult>{

  private ClassADao classADao;
  private ClassBDao classBDao;
  private ClassCDao classCDao;

  public void write(List<? extends ProcessorResult> items){
     for(ProcessorResult result : items){
        classADao.save(result.getClassA());
        classBDao.save(result.getClassB());
        classCDao.save(result.getClassC());
     }
  }
}

请记住,List 中的每个元素传递至ItemWriter映射回 ItemReader 中的单个项目。通常,这也是文件中的一行。要使用 Spring Batch,您必须确保 ItemReader 的返回类型是 ItemProcessor 的输入类型。同时,输入ItemWriterList ItemProcessor 返回的类型。这里的读取器、处理器和编写器不遵循该模式,框架将无法使用它们。一些小的更改应该允许您使用您在框架中编写的代码。

最后,我要指出的是,您可以在没有 ItemProcessor 的情况下执行此操作根本不。你可以只拥有 ItemReader<ProcessorResult>ItemWriter<ProcessorResult>并在 ItemReader 中进行映射。因此,您将逻辑从当前的ItemProcessor移开。相反进入 LineMapper<ProcessorResult> 。然后在 FlatFileItemReader 中使用它然后一切都直接从读者传递给作者。这超出了您的问题范围,而且我更喜欢 XML 配置,因此我将保留它。

关于java - 将单个参数而不是列表传递给 ItemWriter 接口(interface)的 Write() 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45283885/

相关文章:

java - 没有@Query的Spring存储库

java - 手动更改 Spring Batch 元数据表是个坏主意吗?

java - 解码长 XML 文件的单个非根节点

java - 在完成期间引用对象

java - 正则表达式标记日志行

java - 从命令行使用处理时出现 UnsupportedClassVersionError

java - 当主实例为 null 时,实例内的实例是否也会为 null

java - 如何在 Spring @ResponseBody 中使用 Jackson 将 ArrayList<String> 转换为 JSON 对象

java - ReloadingCombinedConfigurationBuilder 在 1 次重新加载后未重新加载

Spring Batch - 读取大型平面文件 - 水平缩放的选择?