• 【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

  • 相关阅读:
    cpp:' data_type * '被视为一个数据类型
    c_cpp: 指针的双重赋值
    python3:面向对象之成员变量(成员变量赋值为元组、字典)
    shell:delete_executable_file 删除当前文件夹的可执行文件(linux)
    php:面向对象之成员变量(数组)
    php:输出关联数组特定范围的数据
    cpp: 指针和引用(class & object)
    解决 raw.githubusercontent.com 无法访问的问题
    容器监控
    wsl2 ubuntu 安装k8s
  • 原文地址:https://www.cnblogs.com/heyang78/p/11747855.html
Copyright © 2020-2023  润新知