首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用JPA分页从32k行Excel将数据持久化到MySql数据库?

如何使用JPA分页从32k行Excel将数据持久化到MySql数据库?
EN

Stack Overflow用户
提问于 2020-12-02 22:18:39
回答 1查看 293关注 0票数 0

我有一个包含32k行的大型Excel文件,以及一个将Excel数据持久化到mySQL数据库的Java代码。我的代码适用于大约6k行,但由于JPA限制,我的代码不能用于整个Excel。我读到它可以用JPA分页来完成,但是到目前为止,我只找到了从DB收集数据(已经持久化了数据)并呈现到UI的信息。Excel文件包含32k药物,这一行将持久化到DB中。

我使用以下方法创建了这个Controller层:

代码语言:javascript
运行
复制
    public ResponseEntity<ResponseMessage> uploadFile(@RequestParam("file") MultipartFile file,
                                                    @RequestParam(defaultValue = "0") int page,
                                                    @RequestParam(defaultValue = "6000") int size) {

        String message = "";

        if (ExcelHelper.hasExcelFormat(file)) {
            try {
// the following 6 row are my patetic attempt to resolve with pagination
               List<Medicine> medicines = new ArrayList<>();
                Pageable paging = PageRequest.of(page, size);
                Page<Medicine> pageMedicamente = medicineRepositoryDao.save(paging);

                medicines = pageMedicamente.getContent();
                medicineService.save(file);

                message = "Uploaded the file successfully: " + file.getOriginalFilename();
                return ResponseEntity.status(HttpStatus.OK).body(new ResponseMessage(message));
            } catch (Exception e) {
                message = "Could not upload the file: " + file.getOriginalFilename() + "!";
                return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseMessage(message));
            }
        }

以及储存层:

代码语言:javascript
运行
复制
@Repository
public interface MedicineRepositoryDao extends JpaRepository<Medicine, Long> {


    Page<Medicine> save( Pageable pageable);

}

还有服务层:

代码语言:javascript
运行
复制
        try {
            List<Medicine> medicines = ExcelHelper.excelToMedicine(file.getInputStream());
            medicineRepositoryDao.saveAll(medicines);
        } catch (IOException e) {
            throw new RuntimeException("fail to store excel data: " + e.getMessage());
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-03 06:48:23

我觉得你把这事搞混了。

  1. 我不认为Spring对您在这里可能坚持的行数有任何相关的限制。但JPA有。JPA保存的是对保存在其第一级缓存中的任何实体的引用。因此,对于大量的行/实体,这占用了内存,并且使一些操作更慢,因为实体被一个接一个地查找或处理。

  1. 分页用于读取实体,而不是保存.

在这种情况下你有几个选择。

  1. 不使用JPA。简单地从文件中写入数据并将其写入数据库,JPA几乎没有任何好处。这几乎可以使用JdbcTemplateNamedParameterJdbcTemplate来执行,而且速度要快得多,因为JPA的开销被跳过了,在这个场景中您也不会从中受益。如果您想使用ORM,您可能想看看Spring,它在概念上更简单,不保留对实体的引用,因此在这个场景中应该显示出更好的特性。我建议您不要在这里使用ORM,因为您似乎没有从实体中受益,所以创建实体然后让ORM从其中提取数据实在是浪费时间。

  1. 将您的导入分成几个批次。这意味着您将持久化,例如,每次保持1000行,将它们写入数据库并提交事务,然后再继续处理下1000行。对于JPA来说,由于上述原因,这几乎是必要的。使用JDBC (即JdbcTemplate&Co),这对于32K行可能不是必需的,但可能会提高性能,并且在插入失败时可能对可恢复性有用。Spring批处理将帮助您实现该功能。

虽然前面的点讨论了批处理,即将导入分解为块,但您还应该查看JDBC端的批处理,其中发送多个语句,或者一次发送多个参数集的单个语句到数据库,这同样应该改进performance.。

最后,

  1. 通常在Javaverse之外有更适合于这项工作的替代方案。有些数据库具有极其高效地加载平面文件的工具。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65116990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档