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

MyBatis 多表關聯查詢:association 與 collection 實現一對一、一對多映射詳解

     編輯:Java 綜合教學

場景痛點

實際開發中,POJO 常包含單個關聯對象(一對一)或集合屬性(一對多),需通過多表關聯查詢一次性裝填。MyBatis 提供 <association> 和 <collection> 兩大標簽優雅解決此問題。

Mapper XML 核心配置

<mapper namespace="cn.net.syl.dao.ProductsMapper">

  <!-- 基礎結果映射 -->
  <resultMap id="BaseResultMap" type="cn.net.syl.model.Products">
    <id column="product_id" property="productId" jdbcType="BIGINT" />
    <result column="product_name" property="productName" jdbcType="VARCHAR" />
    <result column="title" property="title" jdbcType="VARCHAR" />
    <result column="descript" property="descript" jdbcType="VARCHAR" />
    <result column="price" property="price" jdbcType="DOUBLE" />
    ...
  </resultMap>

  <!-- 擴展結果映射:包含一對一、一對多 -->
  <resultMap id="BigResultMap" type="cn.net.syl.model.Products" extends="BaseResultMap">
    <!-- 一對一:產品擴展信息 -->
    <association property="prodExt" javaType="cn.net.syl.model.ProductsExt">
      <id column="product_ext_id" property="productExtId" jdbcType="BIGINT" />
      <result column="product_id" property="productId" jdbcType="BIGINT" />
      ...
    </association>

    <!-- 一對多:產品預覽圖片列表 -->
    <collection property="prodPropImgList" ofType="cn.net.syl.model.ProductsPreviewImages">
      <id column="prev_id" property="prevId" jdbcType="BIGINT" />
      <result column="product_id" property="productId" jdbcType="BIGINT" />
      ...
    </collection>
  </resultMap>

  <!-- 多表聯查語句 -->
  <select id="getProductInfo" resultMap="BigResultMap" parameterType="java.lang.Long">
    SELECT
      a.*, b.detail_descript,
      c.image_url, c.product_id, c.property_id, c.value_id,
      d.value_name
    FROM syl_products a
    JOIN syl_products_ext b ON a.product_id = b.product_id
    JOIN syl_products_preview_images c ON a.product_id = c.product_id
    JOIN syl_property_values d ON c.value_id = d.value_id
    WHERE a.product_id = #{productId}
  </select>

</mapper>

POJO 實體類定義

public class Products {
    private Long productId;
    private String productName;
    // ... 其他基礎字段

    // 一對一關聯對象
    private ProductsExt prodExt;

    // 一對多集合屬性
    private List<ProductsPreviewImages> prodPropImgList;

    // 另一個一對多示例
    private List<ProductPropertyEntity> baseProdPropList;

    // Getter/Setter 省略...
}

關鍵點總結

標簽適用關係核心屬性去重依據
<association>一對一 / 多對一property、javaType結果映射中的 <id> 字段
<collection>一對多property、ofType集合元素映射中的 <id> 字段
  • extends 復用:BigResultMap extends="BaseResultMap" 避免基礎字段重複定義;
  • 主鍵去重:<id> 標簽指定的列必須能唯一標識對象,否則會產生重複對象;
  • 列名別名:SQL 查詢列名與映射 column 需一致,必要時用 AS 起別名;
  • 嵌套查詢替代:數據量極大時,可改用 select 屬性配置嵌套懶加載,但通常聯查性能更優。

最佳實踐建議

  1. 優先使用 resultMap + 聯查 SQL,避免 N+1 問題;
  2. 實體類字段名與數據庫列名遵循駝峰/下劃線映射規範,減少手動 <result> 配置;
  3. 對於只讀查詢,考慮使用 ResultHandler 流式處理大結果集;
  4. 單元測試驗證映射正確性,特別關注集合大小與去重邏輯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved