Java Spring : How to efficiently read and save large amount of data from a CSV file?

标签 java spring spring-mvc spring-boot spring-data-jpa

我正在 Java Spring 中开发一个 Web 应用程序,我希望用户能够从前端上传 CSV 文件,然后查看导入过程的实时进度,导入后他应该能够从导入的数据中搜索各个条目。

导入过程包括实际上传文件(通过 REST API POST 请求发送),然后读取文件并将其内容保存到数据库中,以便用户能够从此数据中进行搜索。

将数据保存到数据库的最快方法是什么?仅循环各行并创建一个新的类对象并通过 JPARepository 为每行保存它会花费太多时间。 10000 行大约需要 90 秒。我需要让它变得更快。我需要在合理的时间内添加 200k 行。

旁注:

我看到了使用 Reactor 的异步方法。这应该会更快,因为它使用多个线程,并且保存行的顺序基本上并不重要(尽管数据在 CSV 中具有 ID)。

然后我还看到了 Spring Batch 作业,但所有示例都使用 SQL。我正在使用存储库,因此我不确定是否可以使用它或者它是否是最佳方法。

最佳答案

This GitHub 存储库比较了 5 种不同的批量插入数据的方法。附件。给他,使用 JdbcTemplate是最快的(他声称在 1.79 [+- 0.50] 秒内处理了 500000 条记录)。如果您使用JdbcTemplate使用 Spring Data,您需要创建一个自定义存储库;请参阅this有关详细说明的文档中的部分。

Spring 数据CrudRepository有一个save需要 Iterable 的方法,所以您也可以使用它,尽管您必须计时以查看它相对于 JdbcTemplate 的性能如何。 。使用Spring Data,步骤如下(摘自here,经过一些编辑)

  1. 地址:rewriteBatchedStatements=true到连接字符串的末尾。
  2. 确保您使用的生成器支持实体中的批处理。例如

    @Id
    @GeneratedValue(generator = "generator")
    @GenericGenerator(name = "generator", strategy = "increment")
    
  3. 使用:save(Iterable<S> entities) CrudRepository的方法保存数据。

  4. 使用:hibernate.jdbc.batch_size配置。

解决方案 #2 的代码是 here .

至于使用多个线程,请记住,从多个线程写入数据库中的同一个表可能会产生表级争用并产生更糟糕的结果。你必须尝试并计时。如何使用 Reactor 项目编写多线程代码是一个完全独立的主题,超出了本文的范围。

HTH。

关于Java Spring : How to efficiently read and save large amount of data from a CSV file?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44936375/

相关文章:

java - Spring MVC : Spring Security 4 doesn't intercept

java - spring-hateoas,如何使用 onMethod 构建超媒体链接时设置占位符值

java - 扩展枚举并在 java 中的重写方法中使用它

Java 反射 : Get a Field's Value where the Field is of an Interface Type

java - Gradle 从不同的模块运行 Spock 集成测试

java - 如何在 SWT 中显示文件的系统图标?

spring - 在编译/构建时从 Spring 代码生成 OpenAPI V3 规范

java - 关于 Spring MVC 与 bootstrap 的问题

java - Spring 事务传播和乐观锁定的问题

java - 使用 Spring HATEOAS 构建模板化搜索资源 uri