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(); } }

接口

interface OrderDao {
  void download(Query query, ResultHandler<OrderDownloadDO> handler);
}

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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM