源码:https://gitee.com/antia11/excel-data-import-demo

背景:客户需要每周会将上传一个 Excel 数据文件,数据量单次为 20W 以上,作为其他模块和报表的基础数据。

客户需求分析:

  1. 数据量为 20W 条左右。
  2. 数据需要去重。
  3. 等待时间不能太长。
  4. 文件中会有错误数据存在,错误数据跳过不进入数据库。

注意点:

  1. 为提高导入速度,选择分批插入,每次插入 1000 条数据。
  2. 在读取数据时判断数据是否正确,不正确不插入。
  3. 对数据进行去重。

实现逻辑:

  1. 首先使用 EasyExcel 实现分批插入数据。
  2. 数据插入完成后,在数据库使用 SQL 的方式进行去重,避免内存溢出。
package com.antia1.demo.service;

import com.alibaba.excel.EasyExcel;
import com.antia1.demo.entity.ExcelDataEntity;
import com.antia1.demo.listener.ExcelDataListener;
import com.antia1.demo.mapper.ExcelDataMapper;
import com.antia1.demo.util.RespBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import java.io.IOException;
import java.util.Map; /**
* Author: anti
* Date: 2022/7/23 16:13
*/
@Service
@Slf4j
public class ExcelDataService { @Autowired
private ExcelDataMapper excelDataMapper; public RespBean importData(MultipartFile file) throws IOException {
//0.获取数据库中的最大id
Map<String, Object> idMap = excelDataMapper.getMaxId();
int maxId = Integer.parseInt(idMap.get("maxId") + ""); //1.读取excel
EasyExcel.read(file.getInputStream(), ExcelDataEntity.class,new ExcelDataListener(excelDataMapper,maxId)).sheet().doRead(); //2.开始去除重复数据
log.debug("全部导入完成,开始进行数据去重");
int count = excelDataMapper.deleteDuplicates();
log.debug("去除重复数据:{}条",count); return RespBean.ok("导入完成");
}
}
package com.antia1.demo.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.antia1.demo.entity.ExcelDataEntity;
import com.antia1.demo.mapper.ExcelDataMapper;
import lombok.extern.slf4j.Slf4j; import java.util.ArrayList;
import java.util.List; /**
* Author: anti
* Date: 2022/7/23 16:10
*/
@Slf4j
public class ExcelDataListener extends AnalysisEventListener<ExcelDataEntity> { private static final int BATCH_COUNT = 1000; private List<ExcelDataEntity> list = new ArrayList<>(); private ExcelDataMapper excelDataMapper; private int primaryKey; private int totalCount; public ExcelDataListener(ExcelDataMapper excelDataMapper, int primaryKey) {
this.excelDataMapper = excelDataMapper;
this.primaryKey = primaryKey;
} @Override
public void invoke(ExcelDataEntity excelDataEntity, AnalysisContext analysisContext) {
primaryKey ++ ;
excelDataEntity.setId(String.valueOf(primaryKey));
list.add(excelDataEntity);
if(list.size() >= BATCH_COUNT){
saveData();
list.clear();
}
} @Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
System.out.println(String.format("数据同步完成,总数量为:%s",totalCount));
} public void saveData(){
if(list.size()>0){
int count = excelDataMapper.insertBatch(list);
totalCount += count;
}
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.antia1.demo.mapper.ExcelDataMapper"> <!--数据插入-->
<insert id="insertBatch" parameterType="java.util.List">
INSERT INTO `demo`.`tb_exceldata` (
`id`,
`code`,
`desc`,
`objectCode`,
`projectCode`,
`other`
)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.id}, #{item.code}, #{item.desc}, #{item.objectCode},#{item.projectCode},#{item.other})
</foreach>
</insert> <!--查询最大id-->
<select id="getMaxId" resultType="java.util.Map">
SELECT IFNULL(MAX(CAST(id AS SIGNED)),0) AS maxId FROM `demo`.`tb_exceldata`
</select> <!--去除重复数据-->
<delete id="deleteDuplicates">
DELETE
FROM
`tb_exceldata`
WHERE
id NOT IN (
SELECT
t.id
FROM
( SELECT MIN( id ) AS id FROM `tb_exceldata` GROUP BY `code`,`desc`,`objectCode`,`projectCode`,`other`) t
)
</delete> </mapper>

基于EasyExcel的大数据量导入并去重的更多相关文章

  1. Mysql 大数据量导入程序

    Mysql 大数据量导入程序<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ...

  2. java excel大数据量导入导出与优化

    package com.hundsun.ta.utils; import java.io.File; import java.io.FileOutputStream; import java.io.I ...

  3. JAVA JDBC大数据量导入Mysql

    转自https://blog.csdn.net/q6834850/article/details/73726707?tdsourcetag=s_pctim_aiomsg 采用JDBC批处理(开启事务. ...

  4. 【Java POI】POI基于事件驱动解析大数据量2007版本Excel,空值导致列错位问题

    1.目前测试了20M的文件,可以读取. 2.支持单个工作表1万+的数据行数,耗时如图. 3.以下是关键地方处理的代码 //Accepts objects needed while parsing. / ...

  5. SQL Server 使用bcp进行大数据量导出导入

    转载:http://www.cnblogs.com/gaizai/archive/2010/04/17/1714389.html SQL Server的导出导入方式有: 在SQL Server中提供了 ...

  6. 使用OPENROWSET、Microsoft.ACE.OLEDB实现大数据量的高效导入

    首先说明使用的环境是:java和Sqlserver. 最近公司需要进行大数据量的导入操作.原来使用的是Apache POI,虽然可以实现功能,但是因为逻辑处理中需要进行许多校验,处理速度太慢,使用多线 ...

  7. MYSQL数据库导入大数据量sql文件失败的解决方案

    1.在讨论这个问题之前首先介绍一下什么是"大数据量sql文件". 导出sql文件.选择数据库-----右击选择"转储SQL文件"-----选择"结构和 ...

  8. MySQL数据库如何解决大数据量存储问题

    利用MySQL数据库如何解决大数据量存储问题? 各位高手您们好,我最近接手公司里一个比较棘手的问题,关于如何利用MySQL存储大数据量的问题,主要是数据库中的两张历史数据表,一张模拟量历史数据和一张开 ...

  9. 利用MySQL数据库如何解决大数据量存储问题?

    提问:如何设计或优化千万级别的大表?此外无其他信息,个人觉得这个话题有点范,就只好简单说下该如何做,对于一个存储设计,必须考虑业务特点,收集的信息如下:1.数据的容量:1-3年内会大概多少条数据,每条 ...

随机推荐

  1. salesforce零基础学习(一百一十三)Trigger中获取IP地址的过程

    本篇参考: https://developer.salesforce.com/docs/atlas.en-us.228.0.apexcode.meta/apexcode/apex_class_Auth ...

  2. API Schema in kubernetes

    目录 什么是schema 数据库中的schema Kubernetes中的schema 通过示例了解schema 什么是schema schema一词起源于希腊语中的form或figure,但具体应该 ...

  3. Java synchronized那点事

    前言 请看上篇:Java 对象头那点事 文章中的源码都有不同程度缩减,来源于openjdk8的开源代码(tag:jdk8-b120). 锁粗化过程 偏向锁 ①:markword中保存的线程ID是自己且 ...

  4. MUI+html5+javascript 点击事件触发页面间传值

    关于如何进行页面转跳,请看 https://www.cnblogs.com/JUNELITTLEPANDA/p/15956176.html,以下跳转方法是采用的其中一种 1-  仅适用于移动端,pc端 ...

  5. SpringBoot 错误(2)

    springBoot整合redis时,报错如下: org.springframework.data.redis.serializer.SerializationException: Cannot de ...

  6. 聚类--DBSCN

    1.什么是DBSCN DBSCAN也是一个非常有用的聚类算法. 它的主要优点:它不需要用户先验地设置簇的个数,可以划分具有复杂形状的簇,还可以找出不属于任何簇的点. DBSCAN比凝聚聚类和k均值稍慢 ...

  7. Redis集群搭建 三主三从

    Redis集群介绍 Redis 是一个开源的 key-value 存储系统,由于出众的性能,大部分互联网企业都用来做服务器端缓存.Redis在3.0版本之前只支持单实例模式 虽然支持主从模式,哨兵模式 ...

  8. 解惑unittest框架中导入HTMLTestRunner模块后正常运行却无法生成HTML报告问题

    1.HTMLTestRunner介绍 HTMLTestRunner是一个第三方的unittest HTML报告库,用于python单元测试框架的TestRunner.它是生成一个HTML报告,以一目了 ...

  9. GIF录制工具下载

    GIF录制工具(GifCam)下载地址: https://files.cnblogs.com/files/blogs/747754/GifCam.rar

  10. 16.Nginx优化与防盗链

    Nginx优化与防盗链 目录 Nginx优化与防盗链 隐藏版本号 修改用户与组 缓存时间 日志切割 小知识 连接超时 更改进程数 配置网页压缩 配置防盗链 配置防盗链 隐藏版本号 可以使用 Fiddl ...