多线程解决大数据批量导出问题(demo)

1.首先从网上找一个到工具类,我这里是ExcelUtils,如下

 

package com.org.util;import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;public class ExcelUtils {// 导出 Excelpublic static Integer exportExcel(SXSSFSheet sheet, List<Object> dataList, Integer currentRow) throws IntrospectionException, InvocationTargetException, IllegalAccessException {if (null == dataList || dataList.size() == 0) {return -1;}// 反射Object object =  dataList.get(0);Class<?> clazz = object.getClass();Field[] fields = clazz.getDeclaredFields();//如果是第一行,创建表头if (0 == currentRow) {SXSSFRow row = sheet.createRow(currentRow++);for (int i = 0; i < fields.length; i++) {SXSSFCell cell = row.createCell(i);cell.setCellValue(fields[i].getName());//设置单元格的值为字段名}}//填充数据for (Object item : dataList) {SXSSFRow row = sheet.createRow(currentRow++);for (int i = 0; i < fields.length; i++) {SXSSFCell cell = row.createCell(i);// get MethodPropertyDescriptor propertyDescriptor = new PropertyDescriptor(fields[i].getName(), item.getClass());Method getMethod = propertyDescriptor.getReadMethod();// valueObject value = getMethod.invoke(item);cell.setCellValue(value.toString());//设置单元格的值为字段值的字符表现形式}}return currentRow;}
}

public class DataBaseTest {private static final ConcurrentHashMap<Integer, FutureTask<Integer>> taskList = new ConcurrentHashMap<>();public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {// mapperSqlSession sqlSession = MyBatisUtils.getSqlSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 查出总数int totalNum = userMapper.getTotalNum();// 10个线程数int taskNum = 10;// 总数据量int avg = (int) Math.floor(totalNum / taskNum);int[] startRows = calcStartRowIndex(totalNum, taskNum);// ExcelSXSSFWorkbook workbook = new SXSSFWorkbook();SXSSFSheet sheet = workbook.createSheet();for (int i = 0; i < taskNum; i++) {final int temp = i;FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {System.out.println("开始执行任务" + temp + "...");HashMap<String, Object> map = new HashMap<>();List<User> userList = null;// 分页查询if (temp == taskNum - 1) {// 如果是最后一个线程map.put("startIndex", startRows[temp] - 1); //9001-1// 计算起始位置到最后的数量map.put("num", totalNum - startRows[temp] + 1); //10001-9001+1userList = userMapper.getListByPage(map);} else {//如果是前九个线程的花执行下面的操作map.put("startIndex", startRows[temp] == 0 ? 0 : startRows[temp] - 1);map.put("num", avg);userList = userMapper.getListByPage(map);}List<Object> dataList = new ArrayList<>();for (User user : userList) {dataList.add(user);}Integer currentRow = ExcelUtils.exportExcel(sheet, dataList, startRows[temp]);System.out.println("任务" + temp + "执行结束...");return currentRow;}});taskList.putIfAbsent(i, futureTask);}int taskIndex = 0;while (true) {FutureTask<Integer> futureTask = taskList.remove(taskIndex++);if (null != futureTask) {futureTask.run();Integer currentRow = futureTask.get();}if (taskList.size() == 0) {// 写入磁盘System.out.println("开始写入磁盘");FileOutputStream fileOutputStream = new FileOutputStream(new File("c:\\users\\che\\desktop\\test01.xlsx"));workbook.write(fileOutputStream);break;}}}// 计算每一趟起始位置public static int[] calcStartRowIndex(int totalNum, int taskNum) {int[] resultArray = new int[taskNum];int avg = (int) Math.floor(totalNum / taskNum);for (int i = 0; i < taskNum; i++) {if (i == 0) {resultArray[i] = i * avg;} else {resultArray[i] = i * avg + 1;}}return resultArray;}public static void addDataSource() {SqlSession sqlSession = MyBatisUtils.getSqlSession();try {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);for (int i = 0; i < 10000; i++) {User user = new User("T" + i, i, "男", "10086", "qwe@qq.com", "日本京都");System.out.println(user);userMapper.addUser(user);}sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {
//            sqlSession.close();}}
}

具体代码示例包在次处

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/162513.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Navicat 技术指引 | GaussDB 数据查看器

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持对GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构同步、协同合作、数据迁移等&#xff09;&#xff0c;这…

读论文模板

文章简介 文章标题&#xff1a;文章链接作者单位&#xff1a;文章来源&#xff1a;会议视频ppt1.他人代码 2.作者代码 文章思路 文章总结 1.解决问题 2.使用方法 3.文章不足

解释器模式 (Interpreter Pattern)

定义 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;用于定义一种语言的语法表示&#xff0c;并提供一个解释器来处理这种语法。这种模式用于实现语言解释器&#xff0c;通常用于专业领域或复杂文本处理中。在解释器模式中&#xff…

220V转12V固定输出12V非隔离芯片WT5106WT5105

220V转12V固定输出12V非隔离芯片WT5106WT5105 今天给大家介绍一款实用芯片&#xff0c;WT5106。它是一款高效率高精度的非隔离降压开关电源恒压控制驱动芯片。 WT5106适用于85VAC~265VAC全范围输入电压的非隔离Buck、Buckboost拓扑结构&#xff0c;小家电、电机驱动、继电器驱…

量子计算争霸战加码?美国将拨款30亿美元发展量子计算

&#xff08;图片来源&#xff1a;网络&#xff09; 美国众议院科学、太空和技术委员会认为&#xff0c;如果不采取措施加速量子计算系统的发展&#xff0c;美国将落后于俄罗斯和中国。 因此&#xff0c;该小组的领导人——主席Frank Lucas&#xff08;共和党&#xff09;和高…

云贝教育 |【PostgreSQL PGCA题目解析5】PostgresSQL是否能够自动检测到死锁,然后退出其中一个事务?

考试科目&#xff1a;PGCA-E-090 考试题量&#xff1a;40 道单项选择题、10 道多项选择题&#xff08;每题 2 分&#xff09; 通过分数&#xff1a;60% 考试时间&#xff1a;60min 本文为云贝教育刘峰&#xff08;微信&#xff1a;yunbee_DBA&#xff09;原创&#xff0c;请…

基于 Modbus 的工业数据采集、控制(part 3)

Modbus 设备(利用 slave 模拟) Modbus 采集程序 client.c #include "client.h"modbus_t *ctx; key_t key_shm, key_msg; int shmid, msgid; struct shm *shm0; struct msgbuf msg0;void *collector(void *arg) {struct shm *p = (struct shm *)arg;while (1){sle…

浏览器事件循环原理 —— JS为何会阻碍渲染?

系列文章目录 第一章 浏览器事件循环原理 —— 浏览器进程模型第二章 浏览器事件循环原理 —— 渲染主线程如何工作&#xff1f;第三章 浏览器事件循环原理 —— 何为异步&#xff1f; 文章目录 系列文章目录 文章目录 前言 代码解析 总结 前言 该文章作用于 “web前端大…

桥接模式 (Bridge Pattern)

定义&#xff1a; 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;用于将抽象部分与其实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过创建一个桥接接口&#xff0c;将抽象类和其实现类解耦&#xff0c;使得修改或扩展独立的抽…

改进YOLOv5 | C3模块改动篇 | 轻量化设计 |骨干引入动态卷积|CondConv

🗝️YOLOv5实战宝典--星级指南:从入门到精通,您不可错过的技巧   -- 聚焦于YOLO的 最新版本, 对颈部网络改进、添加局部注意力、增加检测头部,实测涨点 💡 深入浅出YOLOv5:我的专业笔记与技术总结   -- YOLOv5轻松上手, 适用技术小白,文章代码齐全,仅需 …

信号功率放大器的工作原理和特点是什么

信号功率放大器是一种电子设备&#xff0c;用于将输入信号的功率进行放大&#xff0c;以达到所需的输出功率水平。它在各个领域中都有广泛的应用&#xff0c;包括音频放大器、射频放大器、激光功率放大器等。下面将详细介绍信号功率放大器的工作原理和特点。 工作原理&#xff…

Git使用基础总结(从小白到新手版)

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

只知道ECMAScript 2015(ES6),一篇汇总ECMAScript 2015~ECMAScript 2023新特性

前言 我们常说的ES6也就是ECMAScript 2015是在2015年6月发布的。这个版本引入了许多重要的语言特性和改进&#xff0c;对 JavaScript 进行了深刻的扩展和升级&#xff0c;ES6 是 JavaScript 语言的一个里程碑。所以有时也被称为ES6。这是由于规范的发布年份与实际版本号之间的…

OpenAI“宫斗”新进展!Sam Altman将重返OpenAI担任首席执行官 董事会成员改动

在经过激烈的五天讨论和辩论之后&#xff0c;高调人工智能初创公司OpenAI宣布&#xff0c;其联合创始人之一Sam Altman将回归担任首席执行官。这一决定是对上周Altman突然被解雇的回应&#xff0c;该决定引起了极大的关注和讨论。 OpenAI表示&#xff0c;他们已经达成了与Altm…

德迅云安全-德迅卫士:保障您的主机安全

主机安全是指保证主机在数据存储和处理的保密性、完整性、可用性&#xff0c;包括硬件、固件、系统软件的自身安全&#xff0c;以及一系列附加的安全技术和安全管理措施。 为什么要主机安全&#xff1f; 服务器一旦被黑客入侵&#xff0c;个人和企业面临以下安全风险&#xff…

张弛声音变现课,如何为偶像剧配音?

在为偶像剧进行配音工作时&#xff0c;配音员应当捕捉剧中角色的年轻活力、浪漫的爱情故事以及轻快的生活节奏。偶像剧主要讲述的是青春的爱恋、友谊和梦想追求&#xff0c;因此配音需要传递出剧中的真诚和活泼。为偶像剧配音可以考虑以下几点建议&#xff1a; 鲜明活泼的声音 …

如何判断交流回馈老化测试负载是否合格?

交流回馈老化测试负载是用于模拟实际工作环境中设备运行状态的测试工具&#xff0c;主要用于检测设备的耐久性和稳定性。 负载性能&#xff1a;需要检查负载的性能是否符合设计要求&#xff0c;这包括负载的功率、电流、电压等参数是否在规定的范围内&#xff0c;以及负载的工作…

【AI】行业消息精选和分析(11月23日)

今日动态 1、Sam Altman 重掌 CEO&#xff0c;OpenAI 权力斗争正式「落幕」 2、重磅好消息&#xff1a;语音 ChatGPT 现已向全用户开放 3、NVIDIA 与基因泰克合作&#xff0c;利用生成式 AI 加速药物发现 4、 英伟达Q3营收同比增长206%至181亿美元 黄仁勋&#xff1a;生成式AI时…

Zoho Bigin和标准版CRM有什么区别?

Zoho Bigin是Zoho公司推出的一款针对小微企业设计的CRM系统&#xff0c;它与Zoho CRM一脉相承&#xff0c;但更加轻量级&#xff0c;快速帮助小微企业实现数字化销售。下面来说说&#xff0c;Zoho Bigin是什么&#xff1f;它适合哪些企业&#xff1f; 什么是Zoho Bigin&#x…

【c语言】重温一下动态内存,int数组过大会造成栈错误

项目场景&#xff1a; 项目场景&#xff1a;互助群同学在刷题的过程中&#xff0c;遇到的一个题目&#xff0c;需要申请一个很大数组&#xff0c;于是这个同学就写了int[1000000],其实这样写也没有错&#xff0c;可是运行后却显示栈错误。于是就找到我来请教&#xff0c;我想就…