微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 Java、Spring 启动读取包含 150K 记录的 excel 文件、验证、保留数据库中的行?

如何解决如何使用 Java、Spring 启动读取包含 150K 记录的 excel 文件、验证、保留数据库中的行?

我有一个 Spring Boot 应用程序和一个 REST API 端点,它接收一个包含 15 万行和 5 列的 excel 文件。其中一些列是 Employee 表(sql server)的复合主键列的一部分

表员工: 员工 ID - varchar(20),名称- varchar(50),年龄 - smallint, Effective_date - 日期, expire_date - 日期, last_updated_ts - 时间戳, last_updated_by - varchar(20)

复合主键列:employeeId、name、age、effectiveDate

Excel 列:employeeId、name、age、effectiveDate、expirationDate

Excel 示例: |employeeId|姓名|年龄|有效日期|expiration_date|last_updated_ts|last_updated_by| |-- | -- |-- | -- | -- | -- | -- | |1 |约翰 |25 |2019-05-30| null |2019-05-20 |系统 | |2 |爱丽丝|28 |2017-08-15| 2021-02-15|2020-12-30 |人力资源 | |3 |鲍勃 |35 |2015-10-10| 2018-12-05|2018-11-20 |人力资源|

在这里,约翰从 2019 年 5 月 30 日开始活跃,没有到期日期。 Alice 目前处于活跃状态,但将于 2021 年 2 月 15 日到期。 Bob 已经过期,因为他过去有一个 expire_date。

要求:

输入将是上面的excel文件。我们将不得不进行下面提到的验证并将数据插入/更新到表中。

要求用户将使用 UI 上传此包含员工详细信息的 excel 文件,并应完成以下验证。

  1. 在excel中新增一列isDataValid。它将包含值“Y”或“N”。如果任何一行的验证失败,那么我们将其标记为“N”。否则,它是“Y”。

  2. 每一行都必须有员工 ID、姓名、年龄、有效日期。

  3. expiration_date 是可选的。如果存在,expiration_date 必须 >= Effective_date

  4. excel 的每一行都应该验证数据类型(例如:员工姓名应该只包含字符串,而不是数字等)。

  5. excel每行5列,前4列是Employee表的复合主键列。 excel 中的每一行都必须与 Employee 表进行比较。

    一个。如果该行已存在,但已过期:在 excel 中插入带有数据的新行(带有新的 Effective_date 和 expire_date)。 湾如果该行已存在,但未过期:不要插入带有数据的新行并将 isValid 更新为“N”。 C。如果该行不在表中,则插入数据并将 isValid 标记为“Y”。

输出:应通过 REST API 控制器将 excel 文件以及新创建的列“isValid”发送回用户,以便用户可以确定任何行中是否存在任何验证错误的excel。

流程:

  1. 从 REST API 获取 Excel 文件作为多部分文件输入。
  2. 使用 Apache POI 读取 excel 并获取工作簿和工作表。
  3. 迭代每一行,做上面的验证,检查Employee表是否存在记录,按照上面的验证规则在isValid列的excel行中相应地标记它们。
  4. 如果必须保存/更新该行,请将该行保留在 db 中。
  5. 在 excel 中的所有行都经过迭代、验证并标记为有效或无效后,将其从 REST API 发送回调用方。

问题:

  • 对于大约有 150000 行的 excel 表,验证,我可以遵循什么方法?常规循环,对于 500-1000 条记录的小样本集(取决于数据),JPA saveAll 大约需要 1 分钟。
  • 考虑使用批处理(Spring 批处理),但我如何使其足够快,以便用户能够在最多几分钟内下载 excel。
  • 我找不到足够独特的重复问题。请在评论中提供链接

请建议我一些设计选项,以根据我的要求完成操作。提前致谢。

代码

我们使用 Apache POI 进行 excel 操作

控制器类

@PostMapping(path = "/employee/validation")
public ResponseEntity<InputStreamResource> validateEmployeeAndUpload(@RequestParam multipartfile excelFile) {

sxssfWorkbook workbook = new sxssfWorkbook();
HttpHeaders header = new HttpHeaders();
try{
//All validations handled here
workbook = validateAndGetWorkbook(excelFile);
ByteArrayOutputstream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toArray());

headers.add("Content-disposition","attachment; filename=Employee.xlsx");
return ResponseEntity.ok().headers(header).body(new InputStreamResource(inputStream));
}catch(Exception e){
....return bad request
}
}

员工实体 @PostMapping(path = "/employee/validation") public ResponseEntity<InputStreamResource> validateEmployeeAndUpload(@RequestParam multipartfile excelFile) { sxssfWorkbook workbook = new sxssfWorkbook(); HttpHeaders header = new HttpHeaders(); try{ //All validations handled here workbook = validateAndGetWorkbook(excelFile); ByteArrayOutputstream outputStream = new ByteArrayOutputStream(); workbook.write(outputStream); ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toArray()); headers.add("Content-disposition","attachment; filename=Employee.xlsx"); return ResponseEntity.ok().headers(header).body(new InputStreamResource(inputStream)); }catch(Exception e){ ....return bad request } }

EmployeeId 嵌入式 ID 类
@Entity
@Table(name="employee)
class Employee implements Serializable{

@EmbeddedId
EmployeeId employeeId;

@Column("expiration_date)
Date expirationDate;

@Column("last_updated_ts)
Timestamp lastUpdatedTs;

@Column("last_updated_by)
String lastUpdatedBy;

}

存储库接口

@Entity @Table(name="employee) class Employee implements Serializable{ @EmbeddedId EmployeeId employeeId; @Column("expiration_date) Date expirationDate; @Column("last_updated_ts) Timestamp lastUpdatedTs; @Column("last_updated_by) String lastUpdatedBy; }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。