【二十四】springboot使用EasyExcel和线程池实现多线程导入Excel数据

2023-10-30

  springboot篇章整体栏目: 


【一】springboot整合swagger(超详细

【二】springboot整合swagger(自定义)(超详细)

【三】springboot整合token(超详细)

【四】springboot整合mybatis-plus(超详细)(上)

【五】springboot整合mybatis-plus(超详细)(下)

【六】springboot整合自定义全局异常处理

【七】springboot整合redis(超详细)

【八】springboot整合AOP实现日志操作(超详细)

【九】springboot整合定时任务(超详细)

【十】springboot整合redis实现启动服务即将热点数据保存在全局以及redis(超详细)

【十一】springboot整合quartz实现定时任务优化(超详细)

【十二】springboot整合线程池解决高并发(超详细,保你理解)

【十三】springboot整合异步调用并获取返回值(超详细)

【十四】springboot整合WebService(超详细)

【十五】springboot整合WebService(关于传参数)(超详细)

【十六】springboot整合WebSocket(超详细)

【十七】springboot整合WebSocket实现聊天室(超详细)

【十八】springboot实现自定义全局异常处理

【十九】springboot整合ElasticSearch实战(万字篇)

【二十】springboot整合过滤器实战

【二十一】springboot整合拦截器实战并对比过滤器

【二十二】springboot整合activiti7(1) 实战演示篇

【二十三】springboot整合spring事务详解以及实战

【二十四】springboot使用EasyExcel和线程池实现多线程导入Excel数据

【二十五】springboot整合jedis和redisson布隆过滤器处理缓存穿透

【二十六】springboot实现多线程事务处理_springboot多线程事务

【二十七】springboot之通过threadLocal+参数解析器实现同session一样保存当前登录信息的功能


        在公司开发时,遇到一个很常见的导入功能的需求,需要导入Excel文件,由此想到了阿里巴巴的EasyExcel这个方便的工具,当客户给我说需要支持大数据量导入时,我想到了使用线程池来多线程处理导入数据库这个操作。由此本章记录一下这次操作。

qq交流群导航——>231378628

        首先,整体的大概流程差不多是这个样子:

34cc7eb9e0db4a23b467436114ef46d8.png

效果:

bcb80b85bff7401eb0e44e8c0b3925d2.png

7c9eab447858456b8048c675428d2dcf.png

13ba40214d094da5821ca2a2364e9229.png


        真实项目上是公司封装的RPC框架,这次demo直接使用的前面的整合mybatis-plus的demo来写的。

        首先看下目录结构

1b7fa035b0d04f50bce78e6e27225e8d.png

        图片中框选部分就是本章需要修改到的或者新创建的文件,后面一一解读,下面的描述可以对标这个图片中的类名。

        然后介绍下本章需要做的准备工作:

  • 数据库表
  • 修改application配置文件,修改tomcat的最大文件上传限制(否则excel文件太大,上传会报错)
  • 开启mybatis-plus的批量插入功能,mybatis-plus默认只有insert这个单条插入功能(若自己的项目不使用这个,则不需要,这只是我的demo上没有批量插入方法)
  • 创建excel多线程导入接口所需的各个类

目录

一、准备数据库和Excel文件

二、引入所需依赖

三、修改配置文件,修改文件大小默认限制

四、开启mybatis-plus的批量保存功能

五、创建所需工具类

六、创建业务各层代码

七、创建easyExcel事件监听器

八、创建自定义线程类

九、测试单线程和多线程处理的效率


一、准备数据库和Excel文件

CREATE TABLE `deadman` (
  `uid` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '主键',
  `idCard` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '身份证号',
  `userName` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '死者姓名',
  `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '死者性别',
  `age` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '死者年龄',
  `reason` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '死因',
  `house` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '安排地狱层数',
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;

5449633b604548adb4549857dc1bbb11.png

a6336d9ee76f4d55be580182117ef7aa.png


二、引入所需依赖

        主要是导入easyExcel所涉及的依赖,如下:

a53da7f8bc5c4756a79ff7df845b3692.png


三、修改配置文件,修改文件大小默认限制

        这个必须修改,不然后面接口都进不去,默认tomcat服务器是限制了上传文件的大小的。

spring:
  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 100MB
server:
  tomcat:
    max-swallow-size: 100MB 

四、开启mybatis-plus的批量保存功能

        这次demo整合的rpc框架是Mybatis-plus,所以找了一个方法去实现批量保存,如下:

1、新建一个SpiceSqlInjector类

ab951363527446bc8ca94c4c8cc3e816.png

PS:注意框选部分类名。

2、创建SpiceBaseMapper接口类

4520d0f72e1d479eb73fcb13f31ba43e.png

PS:本来是业务的接口层去继承BaseMapper,此处又它去继承BaseMapper,然后加如上图这个方法,注意名称必须是这个否则后面调用该方法会报错。

3、创建业务所需的Mapper层

26dfc9a9780e49f0beef6d79552b17f0.png

继承刚才自定义的接口类。

由此就可以通过注入DeadManMapper调用上面的方法实现批量插入了。

如下:

e25b87b64dc34bf5989d7ed358c24e7f.png


五、创建所需工具类

        在通过EasyExcel导入时,会涉及到一些数据类型不满足入参之类的,本次demo涉及到如下工具类。

1、MultipartFileToFileUtils

        将传入的MultipartFile类型转为File类型,Controller接收到的是MultipartFile类型,EasyExcel.read方法所需要的是File类型。

328b218fac654016b26bea8cc85bea59.png

2、SpringJobBeanFactory

        在监听器类注入mappe时会报空指针,使用如下工具类继承ApplicationContextAware,获取bean对象。

5331c336ca794d11a20893c3ea2cad44.png


六、创建业务各层代码

1、controller层

5cc57717177c4ba591da40dff13f2b89.png

2、映射数据库的实体类

41e177686af84d949d72f64066f9254d.png

        关于mybatis-plus相关的注解可以去看看前面的文章。 

3、easyExcel的实体类

d7a7fdd6a0f94d51a4362943c9f9a146.png

        index指的是excel表上面的行编号,例如

f3142fff64f14c3bb068db491dcb982f.png

4、service层

87a1ae11359f45b4a2b6f84b2441e7b5.png

5、service的实现类层

ab55f46c075945edb4c0392225184873.png

        上面的方法是多线程处理的事件监听器,下面的是单线程的事件监听器,后面针对两种方式都做一下对比。 


七、创建easyExcel事件监听器

1、单线程的事件监听器

eb0563f8dc6c4b0b87f5b9900bb1524c.png

        解析:该监听器继承自AnalysisEventListener类,泛型指定为上面easyExcel指定的实体类对象类。重写该类的两个方法:invoke和doAfterAllAnalysed。 

invoke():该方法会从excel表的第二行开始读取数据。

doAfterAllAnalysed():当invoke将excel的数据全部解析完后,会执行该方法,所以在该类进行数据的入库即可。

        此时,单线程的导入已经完成,我们最后再对比测试两种监听器的效率,现在创建多线程事件监听器。 

2、多线程的事件监听器

81f5004243134ddb844b91fc1cc8fcf5.png

        解析:同样是重写上面说的那两个方法。invoke方法的处理不变,修改doAfterAllAnalysed方法的处理,在该方法通过创建线程池的方法,将创建的线程任务提交到线程池,让线程池进行多线程任务的执行,从而实现多线程执行导入操作。

流程:创建线程池——》计算每个线程需要处理的数据——》创建CountDownLatch对象(保证最后每个线程会回到主线程)——》循环线程数量并提交线程任务到线程池——》执行CountDownLatch对象的await方法,让当前线程处于等待状态,等待CountDownLatch减少为1后会唤醒当前线程——》每个线程处理自己的数据并在处理完后执行CountDownLatch对象的countDown方法,让CountDownLatch对象的值减一——》当CountDownLatch的值为0时(说明线程池类的线程任务以及执行完成),执行主线程的代码——》关闭线程池

cc0635be4ccd458cae9d00bc2a8f5404.png


八、创建自定义线程类

        此步骤创建上面描述的线程任务类。

dea0cbadd1a543329fa2c75d443e87ed.png

        实现Callable或者Runable或者继承Thread都行,此处实现Runable,重写run方法。

        根据传入的划分给他的数据区间,将该区间的数据通过subList方法取出来之后,执行上面实现的批量插入方法进行数据的入库操作。为了防止代码出现问题不执行coutDown方法,将该句代码写入finally。

PS:CountDownLatch的两个方法(countDown,await)配合使用,保证每个线程的代码执行时,主线程进入等待,然后等各个线程任务执行完后,又回到主线程进行执行。


九、测试单线程和多线程处理的效率

        上面已经完成了单线程和多线程事件监听器的编写,下面开始测试两者的效率。

1、使用单线程事件监听器

d146d90712f345f4b82c2ec8ef9564af.png

40dc9b181abe4e1d8e8b9ab0389966f4.png

84069e3a0f994a2b80fc63688f0b6118.png

c3c6ff95f3bc48b78036e08fe8ad35b0.png

a8ecd2e1f3f449689d7d4ef08ae6b9e9.png​  

acd43a125b7343618a4ef399abd9dc31.png

        结果:100033条数据,数据正确。 

2、使用多线程事件监听器

7be678b60b9f419e951318d446c54514.png

1070455afae046dbac229c7f78c77fed.png

d2620d7b776f410e9b5b9409b5641851.png

        结果:100033条数据,数据正确,确实快了很多。


        我觉得对于业务简单的多线程处理类似场景的都可以拿这个demo拿去改造一下,如果有问题,谢谢大家指出。瑞思拜。

qq交流群导航——>231378628

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【二十四】springboot使用EasyExcel和线程池实现多线程导入Excel数据 的相关文章

  • Java 8 可选

    我想检查特定对象大小是否大于 0 如果它大于 0 那么我想创建一个可选对象 如果不是 那么我想返回一个可选的空对象 这是java代码的长版本 if fooA size gt 0 return Optional of new Foo else
  • import java 导入错误:没有名为 java 的模块

    我似乎遇到了障碍 根本无法解决这个问题 任何人都可以帮我弄清楚为什么我无法导入 java 模块吗 Error Traceback most recent call last File datasource config py line 3
  • 如何创建仅接受字母数字字符的正则表达式? [复制]

    这个问题在这里已经有答案了 可能的重复 字母数字和下划线的正则表达式 https stackoverflow com questions 336210 regular expression for alphanumeric and unde
  • 如何从球衣服务端点发送实体列表?

    我正在从球衣服务器发送实体列表 在客户端 我试图获取这些实体列表 但它给了元帅例外 为什么它在元素名末尾添加 s 即 emps 而不是 emp XmlRootElement public class Emp Server side code
  • 调试器不会停止在 Intellij IDEA 中的源代码处

    我有一个相当奇怪的问题 无法使用 Intellij IDEA 解决 我正在解析电子邮件文件org apache james mime4j包裹 但我的邮件文件格式不兼容Date 标头 因此 我从 mime4j 源创建了模块 并从磁盘中删除了
  • 简单的Java程序插入USB热点后速度慢100倍

    我有以下Java程序 class Main public static void main String args throws java io IOException long start System nanoTime java io
  • 如何注册 org.springframework.integration.monitor.IntegrationMBeanExporter

    根据http www ibm com support knowledgecenter en SS7K4U 8 5 5 com ibm websphere nd multiplatform doc ae cspr data access tr
  • 字符串 a == 字符串 b 的规则 [重复]

    这个问题在这里已经有答案了 我试图了解字符串池的工作原理以及一个字符串等于另一个字符串的规则是什么 例如这个片段 public static void main String hi String s1 lol String s2 lol S
  • 基于磁盘的 HashMap [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Java 是否有 或者是否有可用的库 允许我拥有基于磁盘的 HashMap 它不需要是原子的或任何东西
  • 是否有适用于 Java 的 CalDAV 客户端库? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想使用 CalDAV 协议与我的日
  • 在休眠搜索中使用现有分析器AnalyzerDiscriminator

    Entity Indexed AnalyzerDefs AnalyzerDef name en tokenizer TokenizerDef factory StandardTokenizerFactory class filters To
  • 用二进制数、常规数字和格雷编码填充矩阵

    我有一个包含 1 s 或 0 s 的矩阵 用于创建二进制数 其宽度为n 对于 n 2 和 n 3 它看起来像 00 000 01 001 10 010 11 011 100 101 110 111 等等 现在我正在使用以下代码来生成它 in
  • Java中如何将Object[]转换为String[]?

    我有一个关于 Java 的问题 我有一个Object Java默认的 不是用户定义的 我想将它转换为String 谁能帮我 谢谢 这是转换 for int i 0 i lt objectArr length i try strArr i o
  • Java 日期和 MySQL 时间戳时区

    我正在编辑一段代码 其基本功能是 timestamp new Date 然后坚持下去timestamp中的变量TIMESTAMPMySQL 表列 然而 通过调试我看到Date显示在正确时区的对象 GMT 1 当持久化在数据库上时 它是GMT
  • 如何在列表视图中选择时启用视频序列自动播放?

    大家好 有人可以与我分享一下我如何编写我的 viewvideo java 类 以便它允许自动播放视频功能 自动排序在列表视图中播放所选视频的任务 从当前位置到最新录制的视频 按顺序直到最新的视频播放完毕 这类似于 YouTube 自动播放功
  • 如何预先填充 JFileChooser 将“文件名”?

    我打算用数据库中的名称填充 JFileChooser 但使用标准 JFileChooser 对话框进行加载 删除 保存和另存为 我想给用户留下这样的印象 他们正在处理文件系统 而在后端使用数据库来保存更改 用户不应该能够浏览到不同的目录进行
  • 为什么找不到 getservletcontext?

    我正在尝试使用getServletContext getRealPath 但我不断收到此错误 cannot find symbol symbol method getServletContext location interface jav
  • 原子整数的compareandexchange()与compareandset()

    在研究 AtomicInteger 时 我发现这个 API 提供了两种方法 比较和交换 如果当前值被引用 则自动将该值设置为 newValue to 作为见证值 预期值 记忆效应为 由指定VarHandle compareAndExchan
  • 优雅地避免 Java 中的 NullPointerException

    考虑这一行 if object getAttribute someAttr equals true 显然这一行是一个潜在的错误 属性可能是null我们会得到一个NullPointerException 因此我们需要将其重构为以下两个选择之一
  • SWT StyledText 有高度限制吗?

    我正在尝试创建一个应用程序 其中包含在 ScrolledComposite 中显示的 StyledText 框 我在 StyledText 框中显示大量行时遇到困难 超过 2 550 行似乎会导致问题 StyledText 框本身不能有滚动

随机推荐

  • linux用户登录,鉴定故障

    异常信息 解决方法 1重启linux 按E 结果如图所示 2选择图中全亮的那一行 继续按E 3quite 后面 空格 1 输入完毕按enter 4 按B 5修改密码
  • Android file类使用详解

    一 Android file类 在开发Android应用时免不了会跟文件打交道 本篇文章记录总结自己常用到的文件操作 数据的存储有多种方式 比如数据库存储 SharedPreferences存储 文件存储等 这里我们将要介绍最简单的文件存储
  • 华为虚拟化Kylin Server-10 SP1安装VMTools

    华为虚拟化Kylin Server 10 SP1安装VMTools 环境 虚拟化平台 华为Fusioncompute 8 0 0 ARM 虚拟机操作系统 Kylin Server 10 SP1 Release Build20 2021051
  • [LINUX]虚拟机上cent os7忘记root密码修改root密码

    https blog csdn net dannistang article details 80224871
  • 验证框架的配置及validation.xml常用的验证规则(Struts2的输入验证详解)

    5 很多验证标签的type已经改了 对应的param里面的name属性也改了 针对最新版的struts 建议详细阅读struts的validation html 在docs docs下 比如regex对应的param的name 已经改为 r
  • java利用反射通用导入Excel到数据库

    package com homelink perform module perform util import java lang reflect Field import java lang reflect Method import j
  • Waves 14 Complete for Mac(Waves混音效果全套插件)

    Waves 14 Complete for Mac是一款音频插件套装 拥有多种不同的音频处理插件 高品质音效 简单易用的界面 完全兼容和兼容多平台等特点 可以帮助音频制作人员进行音频处理和混音 提高音频制作的效率和质量 音乐创作是一个永不停
  • ajax nginx 转发 sessionid_nginx搭建及加固

    系统使用的是centos7 Nginx安装及配置 Nginx engine x 是一个高性能的HTTP和反向代理web服务器 同时也提供了IMAP POP3 SMTP服务 安装 我是用的环境是centos 7 系统默认的yum源没有ngin
  • InceptionNext实战:使用InceptionNext实现图像分类任务(二)

    文章目录 训练部分 导入项目使用的库 设置随机因子 设置全局参数 图像预处理与增强 读取数据 设置Loss 设置模型 设置优化器和学习率调整算法 设置混合精度 DP多卡 EMA 定义训练和验证函数 训练函数 验证函数 调用训练和验证方法 运
  • git push 提示 remote: Support for password authentication was removed on August 13, 2021. Please ...

    问题描述 今天把自己翻译的一些内容提交到 GitHub 上 但是 push 后却提示下内容 remote Support for password authentication was removed on August 13 2021 P
  • leetcode格式二叉树生成工具(C++)

    介绍 输入leetcode测试用例类型字符串 返回根节点指针 判断逻辑和leetcode一致 null结点无须额外输入null子结点 并且自动舍弃无效结点 例如输入 1 null 2 null null 3 算法会自动舍弃结点3 网上找的都
  • 2021-05-01

    def print topic texts n topics n words 输出主题模型结果 param n topics LDA主题数量 param n words 主题的词范围 数量 return 输出公共主题 单日主题 准备语料库
  • python中的类与对象

    1 类和对象的关系 类就相当于 lt 模板 gt 或者 lt 模具 gt 对象就相当于 lt 产品 gt 得有了类 我们才能制造各种对象 就像我们有了模具 才能生产各种产品一样 Python中 万事万物都可以是对象 类 这种模板层级的本身也
  • linux入门---如何实现用户切换

    目录标题 基本用户认识 用户的切换 su su exit su 用户名 sudo 基本用户认识 在linux系统中将用户分为两个大类一个是root用户一个是普通用户 root用户是linux操作系统的超级管理员 相当于古代的皇帝不会受到任何
  • spring 事务总结

    参考视频 https www bilibili com video BV1aC4y1p7bF p 5 参考文档 https www cnblogs com myitnews p 12364455 html autoid 4 0 0 事务开启
  • 电源防反接电路设计

    在直流电源系统中 电源的输入端 为了防止电源正负极接反 通常会在输入端对电源进行防反接保护 防反接保护的方法有很多种 今天就来介绍一下 二极管防反接 利用二极管的单向导通特点实现防反接 这种方式是最简单的防反接方法 成本也低 但是缺点也很明
  • 机器学习概述

    一 定义 机器学习是一门从数据中研究算法的科学学科 机器学习直白来讲 是根据已有的数据 进行算法选择 并基于算法和数据构建模型 最终对未来进行预测 通过数据训练出一个模型 gt 预测未知属性 理性认识 输入 x X 属性值 输出 y Y 目
  • string篇

    目录 构造函数原型 赋值重载函数 assign 拼接函数原型 append 查找和替换函数原型 find replace 字符串比较函数 compare 字符存取 at 插入和删除字符串 insert erase 获取子串 substr s
  • Swift 使用CocoaPods 导入第三方网络库——Alamofire

    1 在已经安装了CocoaPods的前提下 cd进入项目所在目录 创建Podfile文件 touch Podfile 2 打开pod file文件 open e Podfile 3 在打开的Podfile文本编辑器里输入 source ht
  • 【二十四】springboot使用EasyExcel和线程池实现多线程导入Excel数据

    springboot篇章整体栏目 一 springboot整合swagger 超详细 二 springboot整合swagger 自定义 超详细 三 springboot整合token 超详细 四 springboot整合mybatis p