特别感谢 https://www.cnblogs.com/barrywxx/p/10700283.html 提供的模板导出的技术和思路

测试环境:

1、jdk1.8  springboot  mybatis  mysql

2、70万条的数据34个字段,因业务需求是60万左右的数据量我这里只测试了70万的

技术和思路:

查询:采用流式查询,每次查询5万条数据

导出:采用模板的形式。用Excel的xml格式处理

代码展示:

controller层:


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import cn.stylefeng.guns.modular.zcManageTemp.service.XMLExportService;@Controller
@RequestMapping("/batchExport")
public class XMLExport {@Autowiredprivate XMLExportService XMLExportService;@ResponseBody@RequestMapping("/exprot")public void getData() throws Exception {long startTimne = System.currentTimeMillis();//模板对象。stringTemplate:只是一个标识,可随便命名StringTemplateGroup stGroup = new StringTemplateGroup("stringTemplate");// 写入excel文件头部信息//这里获取的模板路径是在classpath下的。默认是 resources下的StringTemplate head = stGroup.getInstanceOf("template/head");//创建导出的文件,如果存在会覆盖File file = new File("D:/test/yunda/output11.xls");PrintWriter writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));//对模板里的参数进行设置。我这里就直接设置了要导出的数据行数,列数在模板里写死了也可在这里设置。//如果数据行数以及列数小于你要导出的数据,则文件打不开。大于等于则无影响head.setAttribute("rows", "700100");writer.print(head.toString());writer.flush();// 写入excel文件数据信息StringTemplate body = stGroup.getInstanceOf("template/body");//分批次查询数据和导出数据.导出70万的数据,每次查询导出5万。如果服务器性能好,可以设置大点int size = 700000;int cs = 50000;if (size > 0) {int sang = size / cs;int yu = size % cs;for (int i = 0; i <= sang; i++) {List<Map<String, Object>> selectZCTestData = null;if(i == 0) {selectZCTestData = new ArrayList<Map<String, Object>>(50001);//第一行行头selectZCTestData.addAll(getMap());//注意:这里不要放到for循环外面,否者会出现每次循环都会有这一行的数据(具体原因没找到)}else {selectZCTestData = new ArrayList<Map<String, Object>>(50000);}long l1 = System.currentTimeMillis();//数据查询分页:此处用到了分流查询。否则会出现内存溢出。//如果这里用了分流查询但是服务器的jvm内存太小会导致卡死的问题。我在本地电脑跑的给了1024*3的大小Map<String, Object> map = new HashMap<String, Object>();map.put("star", i * cs);map.put("page", cs);if (i == sang) {if (yu > 0) {selectZCTestData.addAll(XMLExportService.selectZCTestData(map));}} else {selectZCTestData.addAll(XMLExportService.selectZCTestData(map));}System.out.println(i * cs);long l2 = System.currentTimeMillis();System.out.println("第" + i + "次查询用时=" + (l2 - l1));//数据写出if (selectZCTestData.size() > 0) {Worksheet worksheet = new Worksheet();//这个对现场是自己创建的,用于模板里worksheet.setRows(selectZCTestData);body.setAttribute("worksheet", worksheet);writer.print(body.toString());writer.flush();selectZCTestData.clear();selectZCTestData = null;}long l3 = System.currentTimeMillis();System.out.println("第" + i + "次导出用时=" + (l3 - l2));//清空数据XMLExportService.clearList();}}body = null;// 写入excel文件尾部:跟模板要匹配writer.print("</Table>");writer.print("</Worksheet>");writer.print("</Workbook>");writer.flush();writer.close();long endTime = System.currentTimeMillis();System.out.println("导出用时=" + ((endTime - startTimne) / 1000) + "秒");}private List<Map<String, Object>> getMap() {List<Map<String, Object>> retlist=new ArrayList<Map<String, Object>>();Map<String, Object> map = new HashMap<>();List<String> list = getList();list.forEach(p -> {map.put(p, p);});retlist.add(map);return retlist;}private List<String> getList() {List<String> list = new ArrayList<String>();list.add("code_id");list.add("zichan_code");list.add("ciji_num");list.add("pdzc_name");list.add("gongsi_code");list.add("bumen_code");list.add("zichan_name");list.add("zichan_nature");list.add("zichan_fenlei");list.add("zichan_guige");list.add("zichan_type");list.add("zichan_brand");list.add("supplier");list.add("laiyuan_way");list.add("zichan_value");list.add("zichan_zhejiu");list.add("zichan_netvalue");list.add("zichan_num");list.add("zichan_durable");list.add("baoxiuqi");list.add("jilaing_unit");list.add("zhuzichan");list.add("caigou_code");list.add("ruku_riqi");list.add("ruzhang_riqi");list.add("shebei_code");list.add("zeren_man");list.add("zeren_bumen");list.add("zichan_suoshu");list.add("zichan_cunfang");list.add("shiyong_man");list.add("shiyong_bumen");list.add("zichan_state");list.add("remark");return list;}
}

service层:

private List<Map<String, Object>> selectZCTestDataList = new ArrayList<Map<String, Object>>(50000);@Overridepublic List<Map<String, Object>> selectZCTestData(Map<String, Object> map) {//流式读取GxidResultHandler gxidResultHandler = new GxidResultHandler();try {this.baseMapper.selectZCTestData(map, gxidResultHandler);selectZCTestDataList.addAll(gxidResultHandler.getData());} finally {gxidResultHandler.end();}return selectZCTestDataList;}public void clearList() {selectZCTestDataList.clear();}

流式获取结果类:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;public class GxidResultHandler implements ResultHandler<Map<String, Object>> {// 存储每批数据的临时容器private List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(50000);int size = 0;@Overridepublic void handleResult(ResultContext<? extends Map<String, Object>> resultContext) {/** 回调处理逻辑 */list.add(resultContext.getResultObject());}public List<Map<String, Object>> getData() {return list;}// 这个方法给外面调用,用来完成最后一批数据处理public void end() {list.clear();}
}

dao层:

void selectZCTestData(Map<String, Object> map,ResultHandler<Map<String, Object>> handler);

worksheet:

package cn.stylefeng.guns.modular.zcManageTemp.controller;import java.util.List;
import java.util.Map;/*** 类功能描述:Excel sheet Bean**/
public class Worksheet {private String sheet;private int columnNum;private int rowNum;private List<Map<String,Object>> rows;public String getSheet() {return sheet;}public void setSheet(String sheet) {this.sheet = sheet;}public List<Map<String,Object>> getRows() {return rows;}public void setRows(List<Map<String,Object>> rows) {this.rows = rows;}public int getColumnNum() {return columnNum;}public void setColumnNum(int columnNum) {this.columnNum = columnNum;}public int getRowNum() {return rowNum;}public void setRowNum(int rowNum) {this.rowNum = rowNum;}
}

文件导出的模板:

head.st

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"xmlns:o="urn:schemas-microsoft-com:office:office"xmlns:x="urn:schemas-microsoft-com:office:excel"xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"xmlns:html="http://www.w3.org/TR/REC-html40"><DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"></DocumentProperties><OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office"><AllowPNG/></OfficeDocumentSettings><ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel"><WindowHeight>8988</WindowHeight><WindowWidth>23040</WindowWidth><WindowTopX>32767</WindowTopX><WindowTopY>32767</WindowTopY><ProtectStructure>False</ProtectStructure><ProtectWindows>False</ProtectWindows></ExcelWorkbook><Styles><Style ss:ID="Default" ss:Name="Normal"><Alignment ss:Vertical="Center"/><Borders/><Font ss:FontName="等线" x:CharSet="134" ss:Size="11" ss:Color="#000000"/><Interior/><NumberFormat/><Protection/></Style></Styles><Worksheet ss:Name="sheet1"><Table ss:ExpandedColumnCount="34" ss:ExpandedRowCount="$rows$" x:FullColumns="1"x:FullRows="1" ss:DefaultRowHeight="13.8">

body.st

$worksheet:{$it.rows:{<Row><Cell><Data ss:Type="String">$it.code_id$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_code$</Data></Cell><Cell><Data ss:Type="String">$it.ciji_num$</Data></Cell><Cell><Data ss:Type="String">$it.pdzc_name$</Data></Cell><Cell><Data ss:Type="String">$it.gongsi_code$</Data></Cell><Cell><Data ss:Type="String">$it.bumen_code$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_name$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_nature$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_fenlei$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_guige$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_type$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_brand$</Data></Cell><Cell><Data ss:Type="String">$it.supplier$</Data></Cell><Cell><Data ss:Type="String">$it.laiyuan_way$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_value$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_zhejiu$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_netvalue$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_num$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_durable$</Data></Cell><Cell><Data ss:Type="String">$it.baoxiuqi$</Data></Cell><Cell><Data ss:Type="String">$it.jilaing_unit$</Data></Cell><Cell><Data ss:Type="String">$it.zhuzichan$</Data></Cell><Cell><Data ss:Type="String">$it.caigou_code$</Data></Cell><Cell><Data ss:Type="String">$it.ruku_riqi$</Data></Cell><Cell><Data ss:Type="String">$it.ruzhang_riqi$</Data></Cell><Cell><Data ss:Type="String">$it.shebei_code$</Data></Cell><Cell><Data ss:Type="String">$it.zeren_man$</Data></Cell><Cell><Data ss:Type="String">$it.zeren_bumen$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_suoshu$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_cunfang$</Data></Cell><Cell><Data ss:Type="String">$it.shiyong_man$</Data></Cell><Cell><Data ss:Type="String">$it.shiyong_bumen$</Data></Cell><Cell><Data ss:Type="String">$it.zichan_state$</Data></Cell><Cell><Data ss:Type="String">$it.remark$</Data></Cell></Row>}$
}$

结果展示:

0
第0次查询用时=2276
第0次导出用时=3575
50000
第1次查询用时=2090
第1次导出用时=4427
100000
第2次查询用时=2004
第2次导出用时=3705
150000
第3次查询用时=2229
第3次导出用时=3561
200000
第4次查询用时=2374
第4次导出用时=3502
250000
第5次查询用时=2816
第5次导出用时=3452
300000
第6次查询用时=3094
第6次导出用时=2871
350000
第7次查询用时=3085
第7次导出用时=3530
400000
第8次查询用时=2956
第8次导出用时=3148
450000
第9次查询用时=4073
第9次导出用时=3009
500000
第10次查询用时=4384
第10次导出用时=3163
550000
第11次查询用时=5824
第11次导出用时=3053
600000
第12次查询用时=4513
第12次导出用时=3689
650000
第13次查询用时=32630
第13次导出用时=3628
700000
第14次查询用时=0
第14次导出用时=0
导出用时=129秒

结束

从这次结果看,最后一次的查询耗时非常多,可能原因:1、jvm内存 2、主机性能  。总体来说勉强能用,但是还需要继续优化

Java 近百万数据查询和导出共用时2分钟左右相关推荐

  1. Java操作百万数据量Excel导入导出工具类(程序代码教程)

    Java操作百万数据量Excel导入导出工具类(程序代码教程): # 功能实现1.自定义导入数据格式,支持配置时间.小数点类型(支持单/多sheet)(2种方式:本地文件路径导入(只支持xls.xls ...

  2. excel百万数据如何导入导出

    前景 在项目开发中往往需要使用到数据的导入和导出,导入就是从Excel中导入到DB中,而导出就是从DB中查询数据然后使用POI写到Excel上. 写本文的背景是因为在工作中遇到了大数据的导入和导出,问 ...

  3. 百万数据的导入导出解决方案

    300万数据的导入导出 前景: 在项目开发中往往需要使用到数据的导入和导出, 导入就是从Excel中导入到DB中,而导出就是从DB中查询数据然后使用POI写到Excel上. 写本文的背景是因为在工作中 ...

  4. c# mysql timeout expired_C#百万数据查询出现超时问题的解决方法

    本文较为详细的讲解了C#百万数据查询出现超时问题的解决方法,分享给大家供大家参考之用.具体方法如下: 很多时候我们用C#从百万数据中筛选一些信息时,经常会出现程序连接超时的错误,常见的错误有很多,例如 ...

  5. AJAX for Java简单表数据查询实例

    AJAX for Java简单表数据查询实例<?XML:NAMESPACE PREFIX = O /> AJAX WebShop 3对Java开发具有良好的支持,同时也提供了各种层次的后台 ...

  6. Java 百万数据秒级导出到Excel中

    出自: 腾讯课堂 700多分钟干货实战Java多线程高并发高性能实战全集 , 我学习完了之后, 我给 老师在课上说的话做了个笔记,以及视频的内容,还有代码敲了一遍,然后添加了一些注释,把执行结果也整理 ...

  7. java 百万数据查询_java一次性查询几十万,几百万数据解决办法

    java查询一次性查询几十万,几百万数据解决办法 很早的时候写工具用的一个办法. 当时是用来把百万数据打包 成rar文件. 所以用了个笨办法. 希望高手指导一下,有什么好方法没有啊 1.先批量查出所有 ...

  8. java 百万数据查询_JAVA技巧:Java中的大量数据查询

    解决方案一:直接使用ResultSet来处理 从ResultSet中将查询结果读入collection,缓存在HttpSession或有状态bean中,翻页的时候从缓存中取出一页数据显示.这种方法有两 ...

  9. Java将mysql输出csv_使用Java将大量数据从数据库导出到.csv时出...

    我,谢谢您的关注. 我想使用Java将大量数据,实际上是大量数据(600万行)导出到.csv文件.该应用程序是使用toplink(ojdbc14)的JPA摆动应用程序. 我尝试使用: 但是Buffer ...

最新文章

  1. 十二、进程的同步与互斥
  2. C# 调用python
  3. Android NFC开发详细总结
  4. Windows Azure Web Site (17) 设置Web App TimeOut时间
  5. Lesson 3 Part 1 Locally weighted regression
  6. 游戏中出现服务器维护中怎么办,游戏服务器显示维护中
  7. 电能表软件测试用例,一种用于电能表软件自动测试的方法专利_专利查询 - 天眼查...
  8. C++对二进制文件的操作实例
  9. 如何减小电压跟随器输出电阻_电压跟随器秘笈:LM358电压跟随器+运放问题
  10. 2-10配置Linux网络
  11. 全系列三极管应用参数和代换大全
  12. 如何用手机在图片上标箭头_如何在手机上快速给图片做标记?
  13. Type -C 耳机
  14. i7运行linux虚拟机会卡吗,i7 7200 linux 虚拟机
  15. uniapp 二维码展示和扫码
  16. 忽略链路状态的功能详解——网络测试仪实操
  17. Linux 系统基础 — 用户和组(吐血总结,超详细,看这一篇就够了!dog)
  18. python程序设计搜题软件_智慧职教APPPython程序设计答案搜题公众号
  19. Android学习之AlarmManager使用
  20. 【NLP】Praat库(2) Batch processing of files

热门文章

  1. 服务器被黑 追寻ip_网站服务器被攻击了如何查找木马(webshell)IP 篡改的痕迹...
  2. Deployer php自动部署,基于 deployer 的 Web 端自动部署
  3. 对于企业是云服务器划算还是自购服务器划算?
  4. 联阿里接腾讯,B站如何实现“意义非凡”的一年
  5. Adobe国际认证设计师含金量,能否代表设计师的真实水平?
  6. 京东“百亿补贴”提前20小时上线,电商价格战开打; iPhone 15 Pro玻璃面板泄露;凹语言 0.5.0发布|极客头条
  7. 天钰原装FP6606ACAP6芯片,仅5V至20V VBUS电源,过电压保护
  8. 前端vue-高德地图操作
  9. java高并发系列 - 第1天:必须知道的几个概念
  10. 阈的粤语发音_粤语发音规则完整版