Spring Batch中如何读取多个CSV文件合并数据进行处理?

Posted

技术标签:

【中文标题】Spring Batch中如何读取多个CSV文件合并数据进行处理?【英文标题】:How to read multiple CSV files in Spring Batch to merge the data for processing? 【发布时间】:2020-01-19 15:29:06 【问题描述】:

我是 Spring Batch 的新手,并试图获得一些关于以下要求的指导。

总体要求:

我必须从不同的系统获取数据,应用一些业务逻辑,将结果保存到数据库中。

下面是一个例子。

我需要从 3 个 CSV 文件中读取数据。 第一个文件 - person.csv - 包含名称和 ID 第二个文件——address.csv——包含每个人的地址信息。一个人可以有零个或多个地址。 第三个文件——employment.csv——包含每个人的就业信息。一个人可以有零个或多个雇主。

这是一些示例。

Person.csv###(总大小为 800 万)

“人名”、“人名”

1,乔伊

2,钱德勒

3,罗斯

4,莫妮卡

地址.csv

“personID”、“addressType”、“state”

1,住宅,纽约

1、邮寄、NC

2,住宅,纽约

4,住宅,纽约

4、邮寄、DC

就业.csv

"personID", "employerName"

1,雇员1

2, emp2

2, emp3

3, emp4

注意:每个文件都按人员 ID 排序。

要应用业务逻辑,我需要合并每个人的数据,即我需要合并一个人的人员、地址、就业数据以应用逻辑。 你能建议任何方法吗?

【问题讨论】:

Combine rows from 2 files and write to DB using Spring Batch的可能重复 我认为不是重复的。该子链接中的解决方案仅适用于具有相同列和顺序的文件 【参考方案1】:

听起来像是 4 step,工作。您必须决定步骤 1 到 3 的中间结果应该存放在哪里。

如果所有 CSV 文件中的数据都适合内存,那么步骤 1 到 3 的中间结果可能只是 Map,以 personID 作为键。如果不是,那么步骤 1 到 3 的中间结果可能应该写入数据库中的临时表。

假设所有数据都适合内存,创建一个可以注入到步骤 1 到 3 的 ItemWriters 的 bean,例如:

// in a config class...
// assuming PersonID is of type Long
// Assuming Person class has appropriate attributes
Map<Long, Person> people = new HashMap<>();

第 1 步:

ItemReader - 读取下一个 Person.CSV 行并创建一个 Person 实例 ItemProcessor - 无事可做 - 将 Person 实例传递给 ItemWriter ItemWriter - 将 Person 实例添加到 people 地图(或中间表)。

第 2 步:

ItemReader - 读取下一个 Address.CSV 行并创建一个 Address 实例 ItemProcessor - 无事可做 - 将 Address 实例传递给 ItemWriter ItemWriter - 将地址添加到来自people 映射(或中间表)的相关人员。 TODO:如果一个人的地址不存在怎么办?

第 3 步:

ItemReader - 读取下一个就业.CSV 行并创建一个就业实例 ItemProcessor - 无事可做 - 将就业实例传递给 ItemWriter ItemWriter - 将就业添加到来自people 映射(或中间表)的相关人员。 TODO:如果有一个不存在的人的工作应该怎么办?

由于在步骤 1 到 3 中 ItemProcessor 无需执行任何操作,因此使用 Tasklet 可能会更好。

此外,步骤 1 到 3 可以并行完成。它可能会提高性能,但会增加复杂性以确保正确填充 people

第 4 步:

ItemReader - 读取people(或中间表中的复合对象)的下一个元素 ItemProcessor - 应用业务逻辑 ItemWriter - 将结果写入数据库

【讨论】:

感谢安德鲁的意见。 感谢安德鲁的意见。我的批次的有效负载大小非常高。我将有大约 800 万人,并且没有任何临时表。所以,我将无法在内存中处理。因为那里没有临时表,我相信我唯一的选择是使用中间 csv/xml/json。这将增加处理时间。 使用数据库存储步骤 1 到 3 的中间结果。请参阅readers/writers,它可以轻松处理与常见数据库平台的交互。

以上是关于Spring Batch中如何读取多个CSV文件合并数据进行处理?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Batch 简单应用(CSV文件操作)

spring batch csv:向csv添加多个标题

Spring Batch - 从 S3 读取多个文件

Spring-Batch处理MySQL数据后存到CSV文件

如何处理来自 S3 的大文件并在 Spring Batch 中使用它

如何使用 Windows Batch 读取和编辑 (>3GB) csv 文件?