iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >怎么实现java多线程批量拆分List导入数据库
  • 520
分享到

怎么实现java多线程批量拆分List导入数据库

2023-06-25 12:06:27 520人浏览 泡泡鱼
摘要

本篇内容介绍了“怎么实现java多线程批量拆分List导入数据库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!直接把list怼进Mysql使

本篇内容介绍了“怎么实现java多线程批量拆分List导入数据库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

直接把list怼进Mysql

使用mybatis的批量导入操作:

  @Transactional(rollbackFor = Exception.class)    public int addFreshStudentsNew2(List<FreshStudentAndStudentModel> list, String schoolNo) {        if (list == null || list.isEmpty()) {            return 0;        }        List<StudentEntity> studentEntityList = new LinkedList<>();        List<EnrollStudentEntity> enrollStudentEntityList = new LinkedList<>();        List<AllusersEntity> allusersEntityList = new LinkedList<>();        for (FreshStudentAndStudentModel freshStudentAndStudentModel : list) {            EnrollStudentEntity enrollStudentEntity = new EnrollStudentEntity();            StudentEntity studentEntity = new StudentEntity();            BeanUtils.copyProperties(freshStudentAndStudentModel, studentEntity);            BeanUtils.copyProperties(freshStudentAndStudentModel, enrollStudentEntity);            String operator = TenancyContext.UserID.get();            String studentId = BaseUuidUtils.base58Uuid();            enrollStudentEntity.setId(BaseUuidUtils.base58Uuid());            enrollStudentEntity.setStudentId(studentId);            enrollStudentEntity.setIdentityCardId(freshStudentAndStudentModel.getIdCard());            enrollStudentEntity.setOperator(operator);            studentEntity.setId(studentId);            studentEntity.setIdentityCardId(freshStudentAndStudentModel.getIdCard());            studentEntity.setOperator(operator);            studentEntityList.add(studentEntity);            enrollStudentEntityList.add(enrollStudentEntity);            AllusersEntity allusersEntity = new AllusersEntity();            allusersEntity.setId(enrollStudentEntity.getId());            allusersEntity.setUserCode(enrollStudentEntity.getNemtCode());            allusersEntity.setUserName(enrollStudentEntity.getName());            allusersEntity.setSchoolNo(schoolNo);            allusersEntity.setTelNum(enrollStudentEntity.getTelNum());            allusersEntity.setPassword(enrollStudentEntity.getNemtCode());  //密码设置为考生号            allusersEntityList.add(allusersEntity);        }            enResult = enrollStudentDao.insertAll(enrollStudentEntityList);            stuResult = studentDao.insertAll(studentEntityList);            allResult = allusersFacade.insertUserList(allusersEntityList);        if (enResult > 0 && stuResult > 0 && allResult) {            return 10;        }        return -10;    }

Mapper.xml

  <insert id="insertAll" parameterType="com.dmsdbj.itoo.basicInfo.entity.EnrollStudentEntity">        insert into tb_enroll_student        <trim prefix="(" suffix=")" suffixOverrides=",">                id,                  remark,                  nEMT_aspiration,                  nEMT_code,                  nEMT_score,                  student_id,                  identity_card_id,                  level,                  major,                  name,                  nation,                  secondary_college,                  operator,                  sex,                  is_delete,                  account_address,                  native_place,                  original_place,                  used_name,                  pictrue,                  join_party_date,                  political_status,                  tel_num,                  is_reGIStry,                  graduate_school,                  create_time,                  update_time        </trim>                values        <foreach collection="list" item="item" index="index" separator=",">        (                #{item.id,jdbcType=VARCHAR},                #{item.remark,jdbcType=VARCHAR},                #{item.nemtAspiration,jdbcType=VARCHAR},                #{item.nemtCode,jdbcType=VARCHAR},                #{item.nemtScore,jdbcType=VARCHAR},                #{item.studentId,jdbcType=VARCHAR},                #{item.identityCardId,jdbcType=VARCHAR},                #{item.level,jdbcType=VARCHAR},                #{item.major,jdbcType=VARCHAR},                #{item.name,jdbcType=VARCHAR},                #{item.nation,jdbcType=VARCHAR},                #{item.secondaryCollege,jdbcType=VARCHAR},                #{item.operator,jdbcType=VARCHAR},                #{item.sex,jdbcType=VARCHAR},                0,                #{item.accountAddress,jdbcType=VARCHAR},                #{item.nativePlace,jdbcType=VARCHAR},                #{item.originalPlace,jdbcType=VARCHAR},                #{item.usedName,jdbcType=VARCHAR},                #{item.pictrue,jdbcType=VARCHAR},                #{item.joinPartyDate,jdbcType=VARCHAR},                #{item.politicalStatus,jdbcType=VARCHAR},                #{item.telNum,jdbcType=VARCHAR},                #{item.isRegistry,jdbcType=TINYINT},                #{item.graduateSchool,jdbcType=VARCHAR},                now(),                now()                )           </foreach>                  </insert>

代码说明:

底层的mapper是通过逆向工程来生成的,批量插入如下,是拼接成类似: insert into tb_enroll_student()values (),()…….() ;

这样的缺点是,数据库一般有一个默认的设置,就是每次sql操作的数据不能超过4M。这样插入,数据多的时候,数据库会报错Packet for query is too large (6071393 > 4194304). You can change this value on the server by setting the max_allowed_packet' variable.,虽然我们可以通过

类似 修改 my.ini 加上 max_allowed_packet =67108864

67108864=64M

默认大小4194304 也就是4M

修改完成之后要重启Mysql服务,如果通过命令行修改就不用重启mysql服务。

完成本次操作,但是我们不能保证项目单次最大的大小是多少,这样是有弊端的。所以可以考虑进行分组导入。

三、分组把list导入Mysql中

同样适用mybatis批量插入,区别是对每次的导入进行分组计算,然后分多次进行导入:

 @Transactional(rollbackFor = Exception.class)    public int addFreshStudentsNew2(List<FreshStudentAndStudentModel> list, String schoolNo) {        if (list == null || list.isEmpty()) {            return 0;        }        List<StudentEntity> studentEntityList = new LinkedList<>();        List<EnrollStudentEntity> enrollStudentEntityList = new LinkedList<>();        List<AllusersEntity> allusersEntityList = new LinkedList<>();        for (FreshStudentAndStudentModel freshStudentAndStudentModel : list) {            EnrollStudentEntity enrollStudentEntity = new EnrollStudentEntity();            StudentEntity studentEntity = new StudentEntity();            BeanUtils.copyProperties(freshStudentAndStudentModel, studentEntity);            BeanUtils.copyProperties(freshStudentAndStudentModel, enrollStudentEntity);            String operator = TenancyContext.UserID.get();            String studentId = BaseUuidUtils.base58Uuid();            enrollStudentEntity.setId(BaseUuidUtils.base58Uuid());            enrollStudentEntity.setStudentId(studentId);            enrollStudentEntity.setIdentityCardId(freshStudentAndStudentModel.getIdCard());            enrollStudentEntity.setOperator(operator);            studentEntity.setId(studentId);            studentEntity.setIdentityCardId(freshStudentAndStudentModel.getIdCard());            studentEntity.setOperator(operator);            studentEntityList.add(studentEntity);            enrollStudentEntityList.add(enrollStudentEntity);            AllusersEntity allusersEntity = new AllusersEntity();            allusersEntity.setId(enrollStudentEntity.getId());            allusersEntity.setUserCode(enrollStudentEntity.getNemtCode());            allusersEntity.setUserName(enrollStudentEntity.getName());            allusersEntity.setSchoolNo(schoolNo);            allusersEntity.setTelNum(enrollStudentEntity.getTelNum());            allusersEntity.setPassword(enrollStudentEntity.getNemtCode());  //密码设置为考生号            allusersEntityList.add(allusersEntity);        }        int c = 100;        int b = enrollStudentEntityList.size() / c;        int d = enrollStudentEntityList.size() % c;        int enResult = 0;        int stuResult = 0;        boolean allResult = false;        for (int e = c; e <= c * b; e = e + c) {            enResult = enrollStudentDao.insertAll(enrollStudentEntityList.subList(e - c, e));            stuResult = studentDao.insertAll(studentEntityList.subList(e - c, e));            allResult = allusersFacade.insertUserList(allusersEntityList.subList(e - c, e));        }        if (d != 0) {            enResult = enrollStudentDao.insertAll(enrollStudentEntityList.subList(c * b, enrollStudentEntityList.size()));            stuResult = studentDao.insertAll(studentEntityList.subList(c * b, studentEntityList.size()));            allResult = allusersFacade.insertUserList(allusersEntityList.subList(c * b, allusersEntityList.size()));        }        if (enResult > 0 && stuResult > 0 && allResult) {            return 10;        }        return -10;    }

代码说明:

这样操作,可以避免上面的错误,但是分多次插入,无形中就增加了操作实践,很容易超时。所以这种方法还是不值得提倡的。

再次改进,使用多线程分批导入。

四、多线程分批导入Mysql

依然使用mybatis的批量导入,不同的是,根据线程数目进行分组,然后再建立多线程池,进行导入。

  @Transactional(rollbackFor = Exception.class)    public int addFreshStudentsNew(List<FreshStudentAndStudentModel> list, String schoolNo) {        if (list == null || list.isEmpty()) {            return 0;        }        List<StudentEntity> studentEntityList = new LinkedList<>();        List<EnrollStudentEntity> enrollStudentEntityList = new LinkedList<>();        List<AllusersEntity> allusersEntityList = new LinkedList<>();        list.forEach(freshStudentAndStudentModel -> {            EnrollStudentEntity enrollStudentEntity = new EnrollStudentEntity();            StudentEntity studentEntity = new StudentEntity();            BeanUtils.copyProperties(freshStudentAndStudentModel, studentEntity);            BeanUtils.copyProperties(freshStudentAndStudentModel, enrollStudentEntity);            String operator = TenancyContext.UserID.get();            String studentId = BaseUuidUtils.base58Uuid();            enrollStudentEntity.setId(BaseUuidUtils.base58Uuid());            enrollStudentEntity.setStudentId(studentId);            enrollStudentEntity.setIdentityCardId(freshStudentAndStudentModel.getIdCard());            enrollStudentEntity.setOperator(operator);            studentEntity.setId(studentId);            studentEntity.setIdentityCardId(freshStudentAndStudentModel.getIdCard());            studentEntity.setOperator(operator);            studentEntityList.add(studentEntity);            enrollStudentEntityList.add(enrollStudentEntity);            AllusersEntity allusersEntity = new AllusersEntity();            allusersEntity.setId(enrollStudentEntity.getId());            allusersEntity.setUserCode(enrollStudentEntity.getNemtCode());            allusersEntity.setUserName(enrollStudentEntity.getName());            allusersEntity.setSchoolNo(schoolNo);            allusersEntity.setTelNum(enrollStudentEntity.getTelNum());            allusersEntity.setPassword(enrollStudentEntity.getNemtCode());  //密码设置为考生号            allusersEntityList.add(allusersEntity);        });        int nThreads = 50;        int size = enrollStudentEntityList.size();        ExecutorService executorService = Executors.newFixedThreadPool(nThreads);        List<Future<Integer>> futures = new ArrayList<Future<Integer>>(nThreads);        for (int i = 0; i < nThreads; i++) {            final List<EnrollStudentEntity> EnrollStudentEntityImputList = enrollStudentEntityList.subList(size / nThreads * i, size / nThreads * (i + 1));            final List<StudentEntity> studentEntityImportList = studentEntityList.subList(size / nThreads * i, size / nThreads * (i + 1));            final List<AllusersEntity> allusersEntityImportList = allusersEntityList.subList(size / nThreads * i, size / nThreads * (i + 1));           Callable<Integer> task1 = () -> {          studentSave.saveStudent(EnrollStudentEntityImputList,studentEntityImportList,allusersEntityImportList);               return 1;            };          futures.add(executorService.submit(task1));        }        executorService.shutdown();        if (!futures.isEmpty() && futures != null) {            return 10;        }        return -10;    }

代码说明:

上面是通过应用ExecutorService 建立了固定的线程数,然后根据线程数目进行分组,批量依次导入。一方面可以缓解数据库的压力,另一个面线程数目多了,一定程度会提高程序运行的时间。缺点就是要看服务器的配置,如果配置好的话就可以开多点线程,配置差的话就开小点。

“怎么实现java多线程批量拆分List导入数据库”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 怎么实现java多线程批量拆分List导入数据库

本文链接: https://www.lsjlt.com/news/304431.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么实现java多线程批量拆分List导入数据库
    本篇内容介绍了“怎么实现java多线程批量拆分List导入数据库”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!直接把list怼进Mysql使...
    99+
    2023-06-25
  • java多线程批量拆分List导入数据库的实现过程
    目录一、前言二、直接把list怼进Mysql三、分组把list导入Mysql中四、多线程分批导入Mysql五、小结一、前言 前两天做了一个导入的功能,导入开始的时候非常慢,导入2w...
    99+
    2024-04-02
  • Java分批将List数据导入数据库
    目录 一、项目场景:二、为什么要分批次?三、解决方案:1. MyBatisPlus原生方法导入2. List分组导入(1)UserServiceImpl类中导入方法(2)UserMapper数据持久化接口(3)UserMapper....
    99+
    2023-08-19
    java 数据库 mysql
  • SpringBoot用多线程批量导入数据库实现方法
    目录环境原始的for循环入库批量保存操作在批量插入的基础上使用多线程处理多线程入库的事务问题环境 springboot、mybatisPlus、mysql8 mysql8(部署在1核...
    99+
    2023-02-03
    SpringBoot多线程导入数据库 SpringBoot导入数据库 SpringBoot批量导入数据库
  • Java实现多线程大批量同步数据(分页)
    背景 最近遇到个功能,两个月有300w+的数据,之后还在累加,因一开始该数据就全部存储在mysql表,现需要展示在页面,还需要关联另一张表的数据,而且产品要求页面的查询条件多达20个...
    99+
    2022-11-13
    Java同步数据 Java多线程同步数据 Java多线程大批量同步数据
  • Java怎么实现文件批量导入导出
    本篇内容介绍了“Java怎么实现文件批量导入导出”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、介绍java实现文件的导入导出数据库,目前...
    99+
    2023-06-16
  • SQLServer数据库怎么远程查询并批量导入数据
    本篇内容主要讲解“SQLServer数据库怎么远程查询并批量导入数据”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SQLServer数据库怎么远程查询并批量导入...
    99+
    2024-04-02
  • 怎么用java多线程处理大批量数据
    在Java中使用多线程处理大批量数据可以提高程序的处理效率。下面是一个简单的示例代码,演示了如何使用多线程处理大批量数据: impo...
    99+
    2024-04-02
  • Java API如何实现向Hive批量导入数据
    Java API实现向Hive批量导入数据 Java程序中产生的数据,如果导入oracle或者mysql库,可以通过jdbc连接insert批量操作完成,但是当前版本的hive并不支...
    99+
    2024-04-02
  • 怎么在SQL Server数据库中批量导入数据
    今天就跟大家聊聊有关怎么在SQL Server数据库中批量导入数据,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、使用Select In...
    99+
    2024-04-02
  • java之CSV大批量数据入库的实现
    目录需求前期准备代码展示关键代码及思路关键的SQL语句方案选型需求 读200+的CSV/EXCEL文件,按文件名称存到不同数据库 前期准备 环境 maven + jdk8 + mys...
    99+
    2023-02-05
    java CSV大批量入库 java CSV 批量入库
  • 怎么使用java多线程处理大批量数据
    要使用Java多线程处理大批量数据,可以按照以下步骤进行:1. 创建一个线程池:使用Java中的ThreadPoolExecutor...
    99+
    2023-09-26
    java
  • 基于Java SSM如何实现Excel数据批量导入
    今天就跟大家聊聊有关基于Java SSM如何实现Excel数据批量导入,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。导入Maven依赖<dependency>&...
    99+
    2023-06-21
  • 利用Java怎么将excel表格批量导入到数据库
    本篇文章给大家分享的是有关利用Java怎么将excel表格批量导入到数据库,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。创建导入抽象类package com.gclo...
    99+
    2023-05-30
    java excel 数据库
  • Java多线程怎么实现FTP批量上传文件
    这篇文章主要介绍了Java多线程怎么实现FTP批量上传文件的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java多线程怎么实现FTP批量上传文件文章都会有所收获,下面我们一起来看看吧。1、构建FTP客户端pac...
    99+
    2023-07-02
  • Java实现批量导出导入数据及附件文件zip包
    目录前言-应用场景一、导出ZIP包1. 列表数据导出到本地excel文件2. 下载附件信息3. 生成压缩文件(浏览器下载)4. 删除临时目录二、导入ZIP包1. 上传zip包,解压到...
    99+
    2024-04-02
  • 小程序中如何实现excel数据批量导入
    本篇内容介绍了“小程序中如何实现excel数据批量导入”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1 建立数据源要想将数据入库,就先需要建...
    99+
    2023-07-02
  • 利用java怎么实现文件的批量导入导出
    利用java怎么实现文件的批量导入导出?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、介绍利用java实现文件的导入导出数据库,目前在大部分系统中是比较常见的功能了,今天...
    99+
    2023-05-31
    java ava
  • SQLServer批量插入数据怎么实现
    在SQL Server中,可以使用以下方法来实现批量插入数据: 使用INSERT INTO VALUES语句来一次性插入多条数据,...
    99+
    2024-04-09
    SQLServer
  • 使用java怎么向mysql数据库批量插入数据
    今天就跟大家聊聊有关使用java怎么向mysql数据库批量插入数据,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. An...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作