zoukankan      html  css  js  c++  java
  • mybatis + easy excel 导出百万级数据仅需要1g内存

    思路 mybatis 流处理 (实际就是 jdbc 层面的游标,避免分页查询(只需要查询一次数据库)) + easy excel多次写。

    
    
    import org.apache.ibatis.session.ResultHandler
    /**
    * 目前仅支持mybatis的流处理
    * @param query 查询条件的bean
    * @param consumer DAO对应的查询方法
    *             void download(Query query, ResultHandler<OrderDownloadDO> handler);
    * @param excelWriter 由于分层的原因这个需要手动构造来传
    * 参考构造
    * ExcelWriter excelWriter = EasyExcel.write(os, OrderDownloadDTO.class).build();
    * @param <T>
    * @param <S>
    */

    public
    static <T,S> void bigDataExport(T query, BiConsumer<T, ResultHandler<S>> consumer, ExcelWriter excelWriter) { try { WriteSheet[] writeSheet = new WriteSheet[] { EasyExcel.writerSheet(0, "sheet").build() }; List<S> list = new ArrayList<>(1000); // 0 代表当前的条数,等于100万时会被置为0 // 1 代表已经有多少个一百万 int [] c = new int[2]; consumer.accept(query, data -> { c[0]++; list.add(data.getResultObject()); if ((c[0] % 1000) == 0) { excelWriter.write(list, writeSheet[0]); list.clear(); if (c[0] == 1000000) { c[1]++; writeSheet[0] = EasyExcel.writerSheet(c[1], "sheet" + c[1]).build(); c[0] = 0; } } }); //可能有剩余的数据 excelWriter.write(list, writeSheet[0]); } finally { excelWriter.finish(); } }

    XML文件写法

    <select id="download" resultType="xxx.OrderDownloadDO"
                resultSetType="FORWARD_ONLY" fetchSize="1000">
            select * from t_order
    </select>

    调用写法

    ExcelUtils.bigDataExport(query, orderDAO::download, writer);

    实际测试:导出148万左右的数据(10列)只需要130秒左右,内存1g就够,并没有抛出oom。

  • 相关阅读:
    三维体系、点、矢量
    在服务中创建用户进程的方法(C#版)
    C++批判(2)
    MFC五大批判
    Windows服务编写原理及探讨(一)
    Lua常用资源连接
    网友怒批“Linux难敌视窗新七大理由”之我见
    在VC++中实现同步Internet时间
    Lua脚本语法说明(修订)
    Lua 5.0 参考手册
  • 原文地址:https://www.cnblogs.com/math-and-it/p/15465848.html
Copyright © 2011-2022 走看看