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。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值