首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

MyBatis 進階映射完整教學:resultMap 一對一、一對多、多對多、延遲加載與繼承優化

     編輯:Java 相關知識

一、MyBatis 映射兩大方式對比

特性resultTyperesultMap
適用場景扁平化查詢、單表、簡單連接複雜關聯、巢狀結果、延遲加載
映射方式列名自動匹配屬性名手動定義列→屬性、關聯映射
關聯物件需建立扁平化 DTO直接映射到巢狀物件/集合
延遲加載❌ 不支援✅ 支援
繼承複用❌✅ extends 屬性

二、一對一關聯映射:association

場景:查詢訂單 + 關聯用戶

方式 1:resultType + 扁平化 DTO

public class OrderUserDTO extends Order {
    private String username;
    private String sex;
    private String address;
    // getter/setter
}

<select id="findOrderUser" resultType="com.example.dto.OrderUserDTO">
    SELECT o.*, u.username, u.sex, u.address
    FROM orders o JOIN user u ON o.user_id = u.id
</select>

方式 2:resultMap + association(推薦)

public class Order {
    private Integer id;
    private Integer userId;
    private User user;  // 關聯物件
    // getter/setter
}

<resultMap id="orderUserMap" type="com.example.po.Order">
    <id column="id" property="id" />
    <result column="user_id" property="userId" />
    <result column="number" property="number" />
    <result column="createtime" property="createtime" />
    <result column="note" property="note" />
    
    <association property="user" javaType="com.example.po.User">
        <id column="user_id" property="id" />
        <result column="username" property="username" />
        <result column="sex" property="sex" />
        <result column="address" property="address" />
    </association>
</resultMap>

<select id="findOrderUserMap" resultMap="orderUserMap">
    SELECT o.*, u.username, u.sex, u.address
    FROM orders o JOIN user u ON o.user_id = u.id
</select>

三、一對多集合映射:collection

場景:查詢訂單 + 訂單明細(多筆)

public class Order {
    // ... 原有欄位
    private List<OrderDetail> orderDetails; // 集合屬性
}

<resultMap id="orderDetailMap" type="com.example.po.Order" extends="orderUserMap">
    <collection property="orderDetails" ofType="com.example.po.OrderDetail">
        <id column="detail_id" property="id" />
        <result column="items_id" property="itemsId" />
        <result column="items_num" property="itemsNum" />
        <result column="orders_id" property="ordersId" />
    </collection>
</resultMap>

<select id="findOrderDetails" resultMap="orderDetailMap">
    SELECT o.*, u.username, u.sex, u.address,
           d.id detail_id, d.items_id, d.items_num, d.orders_id
    FROM orders o 
    JOIN user u ON o.user_id = u.id
    JOIN order_detail d ON d.orders_id = o.id
</select>

關鍵屬性對比

屬性associationcollection
映射目標單一物件集合
類型指定javaTypeofType
唯一標識子 <id> 必填子 <id> 必填(去重依據)

四、多對多:巢狀 association + collection 組合

場景:用戶 → 訂單(多) → 明細(多) → 商品(一)


<resultMap id="userOrderItemMap" type="com.example.po.User">
    <id column="user_id" property="id" />
    <result column="username" property="username" />
    
    <collection property="orders" ofType="com.example.po.Order">
        <id column="order_id" property="id" />
        <result column="number" property="number" />
        
        <collection property="orderDetails" ofType="com.example.po.OrderDetail">
            <id column="detail_id" property="id" />
            <result column="items_num" property="itemsNum" />
            
            <association property="item" javaType="com.example.po.Item">
                <id column="item_id" property="id" />
                <result column="item_name" property="name" />
                <result column="item_price" property="price" />
            </association>
        </collection>
    </collection>
</resultMap>

五、延遲加載:按需查詢優化效能

全域開啟

<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="false" /> <-- 只加載調用的屬性 -->

映射配置

<association property="user" javaType="User" select="selectUserById" column="user_id" />
<collection property="details" ofType="Detail" select="selectDetailsByOrderId" column="id" />

對應查詢方法

<select id="selectUserById" resultType="User">
    SELECT * FROM user WHERE id = #{user_id}
</select>
<select id="selectDetailsByOrderId" resultType="Detail">
    SELECT * FROM order_detail WHERE orders_id = #{id}
</select>

六、resultMap 繼承優化

<resultMap id="baseOrderMap" type="Order">
    <id column="id" property="id" />
    <result column="user_id" property="userId" />
    <!-- 通用欄位 -->
</resultMap>

<resultMap id="orderWithUserMap" extends="baseOrderMap">
    <association property="user" javaType="User">...</association>
</resultMap>

<resultMap id="orderWithDetailsMap" extends="baseOrderMap">
    <collection property="details" ofType="Detail">...</collection>
</resultMap>

七、選型建議總結

  • 簡單扁平查詢、報表導出 → resultType(開發快)
  • 領域模型豐富、關聯複雜、需延遲加載 → resultMap(維護性好)
  • 高併發讀多寫少 → 開啟二級快取 + 延遲加載
  • 避免 N+1 問題:批量查詢用 collection 一次性載入,或手寫 SQL 聯表
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved