據(jù)集批量導(dǎo)出:ResultHandler 詳解與實(shí)戰(zhàn))
1. 引言在實(shí)際業(yè)務(wù)開(kāi)發(fā)中,數(shù)據(jù)導(dǎo)出是高頻需求。但當(dāng)數(shù)據(jù)量達(dá)到幾十萬(wàn)甚至上百萬(wàn)條時(shí),傳統(tǒng)的selectList一次性加載全部數(shù)據(jù)到內(nèi)存,往往會(huì)導(dǎo)致內(nèi)存溢出(OOM),甚至拖垮整個(gè)應(yīng)用。MyBatis-Plus 提供了ResultHandler機(jī)制,配合流式查詢,可以在遍歷結(jié)果集的同時(shí)逐批處理數(shù)據(jù),從而以極低的內(nèi)存占用完成大數(shù)據(jù)量導(dǎo)出。本文將深入講解ResultHandler的原理、用法,并給出可直接落地的批量導(dǎo)出實(shí)戰(zhàn)代碼。適用讀者本文適合以下讀者閱讀:使用 MyBatis / MyBatis-Plus 進(jìn)行數(shù)據(jù)訪問(wèn)的 Java 后端開(kāi)發(fā)工程師;正在處理大數(shù)據(jù)量導(dǎo)出(如報(bào)表、對(duì)賬、備份)并遇到內(nèi)存溢出問(wèn)題的開(kāi)發(fā)者;希望了解ResultHandler流式查詢?cè)?,并想直接落地到生產(chǎn)項(xiàng)目的同學(xué)。前置知識(shí)閱讀本文前,建議你具備以下基礎(chǔ):熟悉 Java 基礎(chǔ)語(yǔ)法和 Spring Boot 基本用法;了解 MyBatis-Plus 的基本 CRUD 操作(如BaseMapper、Wrapper條件構(gòu)造器);了解 JDBC 連接與事務(wù)的基本概念。目錄概覽章節(jié)內(nèi)容2. 為什么大數(shù)據(jù)量導(dǎo)出會(huì)內(nèi)存溢出分析傳統(tǒng)查詢方式的內(nèi)存問(wèn)題3. ResultHandler 核心原理講解接口定義與ResultContext關(guān)鍵點(diǎn)4. MyBatis-Plus 中使用 ResultHandlerMapper、XML、Service 三層完整用法5. 大數(shù)據(jù)集批量導(dǎo)出實(shí)戰(zhàn)分批收集 + CSV / Excel 批量導(dǎo)出完整代碼6. 流式查詢的注意事項(xiàng)流式配置、事務(wù)與連接占用等要點(diǎn)7. 性能對(duì)比與優(yōu)化建議三種方案對(duì)比與調(diào)優(yōu)方向8. 常見(jiàn)問(wèn)題排查典型報(bào)錯(cuò)的原因與解決方案9. 總結(jié)核心要點(diǎn)回顧2. 為什么大數(shù)據(jù)量導(dǎo)出會(huì)內(nèi)存溢出2.1 傳統(tǒng)查詢方式的問(wèn)題// 一次性加載全部數(shù)據(jù)到內(nèi)存ListUseruserList=userMapper.selectList(null);當(dāng)userList達(dá)到 50 萬(wàn)條時(shí),每條記錄按 200 字節(jié)估算,僅對(duì)象本身就需要約 100MB 內(nèi)存,再加上 MyBatis 內(nèi)部的結(jié)果集映射、List 擴(kuò)容等開(kāi)銷,內(nèi)存占用會(huì)成倍增長(zhǎng)。2.2 內(nèi)存占用分析數(shù)據(jù)量估算內(nèi)存占用風(fēng)險(xiǎn)1 萬(wàn)條約 2~5 MB低10 萬(wàn)條約 20~50 MB中50 萬(wàn)條約 100~250 MB高100 萬(wàn)條約 200~500 MB極高,極易 OOM注意:以上僅為粗略估算,實(shí)際占用取決于字段數(shù)量和類型。3. ResultHandler 核心原理3.1 什么是 ResultHandlerResultHandler是 MyBatis 提供的一個(gè)結(jié)果集處理接口,它允許我們?cè)?MyBatis 遍歷數(shù)據(jù)庫(kù)結(jié)果集的過(guò)程中,逐行(或逐批)回調(diào)自定義邏輯,而不是等所有結(jié)果都映射完成后再統(tǒng)一返回。publicinterfaceResultHandlerT{voidhandleResult(ResultContext?extendsTresultContext);}3.2 與普通查詢的對(duì)比普通查詢 selectList一次性加載全部結(jié)果映射為 List 對(duì)象內(nèi)存占用高,易 OOMResultHandler 流式查詢逐行讀取結(jié)果集