【SpringBoot】整体下载大文件与分批下载大文件(利用MySql数据库的Limit实现)
在前文里谈过一次性从数据库取一个大结果集有可能导致outofMemory,当时的想法是分批去取回来,今天把它实现了,特地把代码分享出来:
工程下载:https://files.cnblogs.com/files/xiandedanteng/CsvDownload20191027.rar
生成CSV文件的三个不同函数
package com.hy.csvdld.util;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import org.apache.log4j.Logger;
import com.hy.csvdld.Entity.Emp;
import com.hy.csvdld.service.EmpService;
// 用于生成CSV文件
public class CsvMaker {
private static Logger log = Logger.getLogger(CsvMaker.class);
public void makeTenCsv(File file, EmpService empService) {
try {
List<Emp> emps = empService.selectTenEmp();
FileWriter fileWriter = new FileWriter(file, true);
int index = 0;
for (Emp emp:emps) {
index++;
String info =""+index+","+ emp.asCsvLine()+ System.getProperty("line.separator");
fileWriter.write(info);
}
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 整体下载方案
public void makeManyCsv(File file, EmpService empService,int count) {
try {
List<Emp> emps = empService.selectMany(count);
FileWriter fileWriter = new FileWriter(file, true);
int index = 0;
for (Emp emp:emps) {
index++;
String info =""+index+","+ emp.asCsvLine()+ System.getProperty("line.separator");
fileWriter.write(info);
}
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 当count过大时,分批下载
public void makePartialCsv(File file, EmpService empService,int count) {
try {
int PartialSize=10000;
int times=count/PartialSize;
for(int i=0;i<times;i++){
log.info("第"+i+"批次处理");
FileWriter fileWriter = new FileWriter(file, true);
List<Emp> emps = empService.selectPartial(i*PartialSize, PartialSize);
int index = i*PartialSize;
for (Emp emp:emps) {
index++;
String info =""+index+","+ emp.asCsvLine()+ System.getProperty("line.separator");
fileWriter.write(info);
}
fileWriter.flush();
fileWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
具体SQL实现:
<?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.hy.csvdld.dao.EmpMapper">
<select id="selectTenEmp" resultType="com.hy.csvdld.Entity.Emp">
select id,name,age,cdate as ctime from emp order by id limit 10
</select>
<!-- 一次性取够 -->
<select id="selectManyEmp" resultType="com.hy.csvdld.Entity.Emp">
select id,name,age,cdate as ctime from emp order by id limit #{count}
</select>
<!-- 分批多次取 -->
<select id="selectPartialEmp" resultType="com.hy.csvdld.Entity.Emp">
select id,name,age,cdate as ctime from emp order by id limit #{start},#{size}
</select>
</mapper>
程序的优化,归根结底是两条路:空间换时间 或是 时间换空间,本文的分批取做法,是时间换空间的路数。
--END-- 2019年10月27日16:06:54
【SpringBoot】整体下载大文件与分批下载大文件(利用MySql数据库的Limit实现)的更多相关文章
- 利用MySQL数据库如何解决大数据量存储问题?
提问:如何设计或优化千万级别的大表?此外无其他信息,个人觉得这个话题有点范,就只好简单说下该如何做,对于一个存储设计,必须考虑业务特点,收集的信息如下:1.数据的容量:1-3年内会大概多少条数据,每条 ...
- PHP7语法知识(四):目录文件操作、Cookie与Session、MySQL数据库的使用、Redis数据库、PHP处理XML与JSON
目录文件操作 一.目录 1.判断文件类型: 2.创建和删除目录: 3.打开读取和关闭目录 4.获得路径中目录部分 5.目录磁盘空间 二.文件操作 1.打开文件: 2.读取文件: 3.获得文件属性: 4 ...
- 大数据入门到精通13--为后续和MySQL数据库准备
We will be using the sakila database extensively inside the rest of the course and it would be great ...
- 利用mysql数据库日志文件获得webshell
查看配置 show variables like '%general%'; 开启日志功能 set GLOBAL general_log='ON'; 设置日志存储路径 SET GLOBAL genera ...
- 大数据的存储——HBase、HIVE、MYSQL数据库学习笔记
HBase 1.hbase为查询而生,它通过组织机器的内存,提供一个超大的内存hash表,它需要组织自己的数据结构,表在hbase中是物理表,而不是逻辑表,搜索引擎用它来存储索引,以满足实时查询的需求 ...
- JavaWeb 文件上传下载
1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程.例如目前网站需要上传头像.上传下载图片或网盘等功能都是利用文件上传下 ...
- 转载:JavaWeb 文件上传下载
转自:https://www.cnblogs.com/aaron911/p/7797877.html 1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端 ...
- MySQL数据库如何解决大数据量存储问题
利用MySQL数据库如何解决大数据量存储问题? 各位高手您们好,我最近接手公司里一个比较棘手的问题,关于如何利用MySQL存储大数据量的问题,主要是数据库中的两张历史数据表,一张模拟量历史数据和一张开 ...
- MySQL数据库中.SQL文件的导出方式
转自:http://tech.watchstor.com/management-117401.htm 在MySQL数据库中导入SQL文件是件很麻烦的事情,但是这是一项大家非常值得学习的技术,本文就从最 ...
随机推荐
- Go微服务 grpc/protobuf
了解grpc/protobuf gRPC是一个高性能.通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers ...
- ubuntu打开终端
虚拟终端 Ctrl+Alt+T组合键 实际终端 Ctrl+Alt+F1 ~ F6组合键 可以在登录界面直接切换 退出终端 Ctrl+Alt+F7组合键
- leetcode-174. Dungeon Game 地下城游戏
一道关于骑士救公主故事的题目. 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过 ...
- 自定义flask转换器
自定义flask转换器 以匹配手机号为例: # 1. 定义自己的转换器 class MobileConverter(BaseConverter): def __init__(self, url_map ...
- 转:applicationContext.xml文件放置位置不同而导致的jUnit测试的时候路径的不同
如果applicationContext.xml文件放置在src下面的的时候使用jUint测试的时候编写的路径应该是这样的: @Test public void saveTest() { Applic ...
- Ubuntu系统---安装English版本之后的一些工作
Ubuntu系统---安装English版本之后的一些工作 安装完U ...
- linux(3)
一.用户和组的管理 Linux/Unix是多用户系统: root是超级用户,拥有最高权限.其它用户及权限由root来管理.对比Windows系统: 控制面板 -> 管理工具 -> 计算机管 ...
- java学习笔记15-封装
把属性(成员变量)设置为私有(private),把方法设置为共有的(public),假如外界想要得到或者改变某个属性,只能通过方法来办到,这其实是封装的思想之一. 新建一个Student类,这个类有几 ...
- [转]从Deadlock报错理解Go channel机制
原文: https://www.jianshu.com/p/147bd63801b6 -------------------------------------- Go与其他语言不一样,它从语言层面就 ...
- python+Appium自动化:日志logging模块
日志级别 debug.info.warn.error.critical五个级别 logging模块构成(四部分) logger(记录器,用于日志采集) Handler(处理器,将日志记录发送到合适的路 ...