源码: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. Microsoft Graph 的 .NET 6 之旅

    这是一篇发布在dotnet 团队博客上由微软Graph首席软件工程师 Joao Paiva写的文章,原文地址: https://devblogs.microsoft.com/dotnet/micros ...

  2. IIS发布Https和Https的问题

    asp.net调试页面的时候遇到一个问题,我喜欢右键点击在浏览器查看页面,打开的页面默认是https的,其实iis会同时生成http和https两种页面,但是我懒得每次去点.问题是页面中测试接口是ht ...

  3. deepin安装jdk配置环境

    下载一个jdk压缩包https://download.oracle.com/java/18/latest/jdk-18_linux-x64_bin.tar.gz 这个包,不用安装,下下来,直接解压,然 ...

  4. java高级用法之:JNA中的回调

    目录 简介 JNA中的Callback callback的应用 callback的定义 callback的获取和应用 在多线程环境中使用callback 总结 简介 什么是callback呢?简单点说 ...

  5. drools的简单入门案例

    一.背景 最近在学习规则引擎drools,此处简单记录一下drools的入门案例. 二.为什么要学习drools 假设我们存在如下场景: 在我们到商店购买衣服的时候,经常会发生这样的事情,购买1件不打 ...

  6. Packed Ciphertexts in LWE-based Homomorphic Encryption:解读

    本节内容记录阅读该论文的笔记 介绍 首先,介绍了两种明文"打包"的方法:PVW和SV PVW:对应论文(PVW:A framework for efficient and comp ...

  7. 好客租房48-组件的props(基本使用)

    组件是封闭的 要接受外部数据应该通过props来实现 props的作用:接受传递给组件的数据 传递数据:给组件标签添加属性 接收数据:函数组件通过参数props接收数据 类组件通过this.props ...

  8. 105_Power Pivot财务科目(层级深度&筛选深度)

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 1.背景 在财务科目中,需要按照科目层级来显示:在excel中都是用公式来实现,而且对于数据的管理及更新是一件头痛的事情, ...

  9. 使用 awk 命令统计文本

    2022-04-19 11:25:15.008,b4d13bfca8fe4b93a85e65a88520d945,LogScheduler#printLog,10ms,Y,xxxxxxxx 2022- ...

  10. 第6组 Alpha冲刺 (5/6)

    目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2. 方梓涵 3.董翔云 4.杜筱 5.詹鑫冰 6.黄少丹 7.曹兰英 8.鲍凌函 9.曾丽莉 10.吴沅静 1.3 冲刺成果展示 1.1 基 ...