我正在使用 Spring Batch 从 CSV 文件读取数据,然后将其保存到数据库中。到目前为止,一切都很好,除了我的输入文件包含混合数据(多个表的多个列)。
我创建了一个类CsvFileLine
它将包含文件的整行,并实现接口(interface) ItemReader<CsvFileLine>
然后实现接口(interface)ItemProcessor<List<CsvFileLine>, ProcessorResult>
我将向其传递 CsvFileLine
的列表它返回 ProcessorResult
类型的对象我也创建了它并包含 3 ArrayList<>
的ClassA
, ClassB
和ClassC
.
我现在的问题是当我需要实现接口(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
的输入类型。同时,输入ItemWriter
是 List
ItemProcessor
返回的类型。这里的读取器、处理器和编写器不遵循该模式,框架将无法使用它们。一些小的更改应该允许您使用您在框架中编写的代码。
最后,我要指出的是,您可以在没有 ItemProcessor
的情况下执行此操作根本不。你可以只拥有 ItemReader<ProcessorResult>
和ItemWriter<ProcessorResult>
并在 ItemReader
中进行映射。因此,您将逻辑从当前的ItemProcessor
移开。相反进入 LineMapper<ProcessorResult>
。然后在 FlatFileItemReader
中使用它然后一切都直接从读者传递给作者。这超出了您的问题范围,而且我更喜欢 XML 配置,因此我将保留它。
关于java - 将单个参数而不是列表传递给 ItemWriter 接口(interface)的 Write() 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45283885/