MyBatis 多表查詢三種最常見的寫法
前言:一張關聯(lián)表,讓你頭禿了嗎?
你是不是也寫過這種需求:
- 查詢某個用戶及其角色列表
- 查詢訂單及明細
- 查詢項目及其下屬的多個階段和負責人
最后寫了一堆復雜 SQL + resultMap,運行一看,要么數(shù)據(jù)重復、要么數(shù)據(jù)丟失,最慘還可能觸發(fā) N+1 查詢……
其實問題不是 MyBatis 不行,而是你用的方法不對。
?? 三種最常見的寫法
? 方式一:聯(lián)表查詢 + 扁平映射(推薦)
這是我最常用也最穩(wěn)定的一種方式:寫一條聯(lián)表 SQL,把需要的字段都查出來,返回扁平結構,再在 Java 層進行組裝。
示例 SQL:
SELECT u.id AS userId, u.name AS userName, r.id AS roleId, r.name AS roleName FROM user u LEFT JOIN user_role ur ON u.id = ur.user_id LEFT JOIN role r ON ur.role_id = r.id
特點:
- 一條 SQL 查全所有數(shù)據(jù);
- 性能高,邏輯直觀;
- 可與分頁插件(如 PageHelper)完美配合。
我的建議:
Java 層用 Map<Long, UserDTO>
分組封裝,適合在 Service 層統(tǒng)一做聚合邏輯。
?? 方式二:嵌套結果(resultMap + collection)
適合結構較為清晰的“樹狀結構”,比如訂單和訂單項、項目和子模塊。
示例 XML:
<resultMap id="userMap" type="User"> <id property="id" column="user_id"/> <result property="name" column="user_name"/> <collection property="roles" ofType="Role"> <id property="id" column="role_id"/> <result property="name" column="role_name"/> </collection> </resultMap>
特點:
- 多表映射層級清晰;
- 比較適合中小型數(shù)據(jù)量。
踩坑經驗:
- 寫錯列名字段,就會導致內層集合全是 null;
- 出現(xiàn)重復數(shù)據(jù)時,要手動去重或用 Set;
- 不適合配合分頁,容易導致“分頁的是主表,但集合是全量”。
?? 方式三:嵌套查詢(nested select)
適合邏輯解耦,按模塊維護的場景。
示例 XML:
<collection property="roles" ofType="Role" select="selectRolesByUserId" column="id"/>
特點:
- 每條主表數(shù)據(jù)觸發(fā)一次副查詢;
- 易維護但 極易 N+1;
- 不適合大批量數(shù)據(jù)查詢。
實戰(zhàn)建議:
除非你能保證每次最多查詢 10 條主記錄,否則慎用。性能瓶頸很容易出現(xiàn)在這里!
?? 你可能踩過的坑
問題 | 癥狀 | 原因 | 建議 |
---|---|---|---|
查詢結果為 null | 子集合沒數(shù)據(jù) | 字段名或別名不匹配 | 顯式寫 column 屬性或使用 @Results 映射 |
一對多重復數(shù)據(jù) | 主表字段重復出現(xiàn) | 聯(lián)表未分組 / Java 封裝沒處理 | 手動分組聚合,避免直接用 List |
分頁異常 | 只分頁主表,子表數(shù)據(jù)混亂 | 不支持嵌套分頁 | 聯(lián)表 + 扁平查詢是最佳方案 |
查詢慢到爆炸 | N+1 查詢 | 每條主記錄觸發(fā)一次 select | 轉成 join 聯(lián)查或改為批量查 |
? 實戰(zhàn)建議:如何選擇這三種方式?
類型 | 性能 | 可維護性 | 適合場景 |
---|---|---|---|
聯(lián)表扁平查詢 | ????? | ?? | 大批量、一對多、分頁場景 |
嵌套結果 resultMap | ??? | ???? | 結構清晰、數(shù)據(jù)量適中 |
子查詢 nested | ?? | ????? | 小數(shù)據(jù)量、邏輯獨立場景 |
?? 我的最佳實踐模板(真實項目用的)
- DAO 層只查數(shù)據(jù),不做結構組裝;
- Service 層按業(yè)務模型拼裝 DTO;
- 多表結果不要直接給前端,統(tǒng)一封裝響應結構;
- DTO + Builder 模式 + Map 分組,靈活好用;
?? 總結一句話:
多表查詢選對方式,寫代碼少掉一半 bug。
不必糾結哪種方式最“完美”,關鍵是是否適合你當前場景。
記住:能用聯(lián)查查全的,就別搞子查詢;分頁場景盡量別用嵌套結構;小數(shù)據(jù)就圖方便,結構優(yōu)先。
到此這篇關于MyBatis 多表查詢的文章就介紹到這了,更多相關MyBatis 多表查詢內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot監(jiān)聽Redis key失效事件的實現(xiàn)代碼
這篇文章給大家介紹了SpringBoot實現(xiàn)監(jiān)聽Redis key失效事件的方法,文中通過代碼示例給大家講解的非常詳細,具有一定的參考價值,需要的朋友可以參考下2024-02-02Spring Boot插件spring tool suite安裝及使用詳解
這篇文章主要介紹了Spring Boot插件spring tool suite安裝及使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08Intellij IDEA實現(xiàn)SpringBoot項目多端口啟動的兩種方法
有時候使用springboot項目時遇到這樣一種情況,用一個項目需要復制很多遍進行測試,除了端口號不同以外,沒有任何不同。遇到這種情況怎么辦呢?這時候可以使用Intellij IDEA解決2018-06-06