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

MyBatis 進階映射:resultMap 實現一對一與一對多關聯查詢實戰

     編輯:Java 綜合教學

項目結構與配置

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/order
jdbc.username=root
jdbc.password=root

SqlMapConfig.xml 核心配置

<configuration>
  <properties resource="db.properties"/>
  <typeAliases>
    <package name="com.mybatis.bean"/>
  </typeAliases>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <package name="com.mybatis.mapper"/>
  </mappers>
</configuration>

實體類設計

// User.java
public class User implements Serializable {
    private int id;
    private String username;
    private Date birthday;
    private List orders; // 1 對多
    // getter/setter
}

// Orders.java
public class Orders {
    private int id;
    private int user_id;
    private String order_number;
    private User user; // 多對 1
    private List orderdetails; // 1 對多
    // getter/setter
}

// Orderdetail.java
public class Orderdetail {
    private int id;
    private int orders_id;
    private int item_id;
    private int item_num;
    private Float item_price;
    private Items items; // 多對 1
    // getter/setter
}

// Items.java
public class Items {
    private int id;
    private String item_name;
    private Float item_price;
    private String item_detail;
    // getter/setter
}

Mapper XML 關鍵映射

<mapper namespace="com.mybatis.mapper.OrderMapper">

  <!-- 一對一:訂單 -> 用戶 -->
  <resultMap type="Orders" id="orderUserResultMap">
    <id column="id" property="id"/>
    <result column="order_number" property="order_number"/>
    <result column="user_id" property="user_id"/>
    <association property="user" javaType="com.mybatis.bean.User">
      <id column="user_id" property="id"/>
      <result column="username" property="username"/>
      <result column="birthday" property="birthday"/>
    </association>
  </resultMap>

  <!-- 一對多:訂單 -> 明細列表 (繼承上面 resultMap) -->
  <resultMap type="Orders" id="orderUserDetailResultMap" extends="orderUserResultMap">
    <collection property="orderdetails" ofType="com.mybatis.bean.Orderdetail">
      <id column="order_detail_id" property="id"/>
      <result column="item_id" property="item_id"/>
      <result column="item_num" property="item_num"/>
      <result column="item_price" property="item_price"/>
    </collection>
  </resultMap>

  <!-- 查詢 1:resultType 簡單映射 (扁平化 DTO) -->
  <select id="findOrderUserList" resultType="OrderUserCustom">
    SELECT o.id, o.order_number, o.user_id, u.username, u.birthday
    FROM orders o INNER JOIN user u ON o.user_id = u.id
  </select>

  <!-- 查詢 2:resultMap 一對一 -->
  <select id="findOrderUserListByResultMap" resultMap="orderUserResultMap">
    SELECT o.id, o.order_number, o.user_id, u.username, u.birthday
    FROM orders o INNER JOIN user u ON o.user_id = u.id
  </select>

  <!-- 查詢 3:resultMap 一對多 -->
  <select id="findOrderItemsList" resultMap="orderUserDetailResultMap">
    SELECT o.id, o.order_number, o.user_id, u.username, u.birthday,
           od.item_id, od.item_num, od.item_price, od.id as order_detail_id
    FROM orders o
    INNER JOIN user u ON o.user_id = u.id
    LEFT JOIN orderdetail od ON o.id = od.orders_id
  </select>

</mapper>

Mapper 接口

public interface OrderMapper {
    List findOrderUserList() throws Exception;
    List findOrderUserListByResultMap() throws Exception;
    List findOrderItemsList() throws Exception;
}

關鍵點解析

場景映射標籤關鍵屬性
一對一 (多方持有一方)<association>property=對象屬性名, javaType=對象全限定名
一對多 (一方持有多方集合)<collection>property=集合屬性名, ofType=集合泛型類型
resultMap 復用extends繼承父 resultMap,避免重複定義
主鍵去重<id>標識唯一列,MyBatis 據此合併同一對象

SQL 寫法注意

  • 列名別名 as 對應 property,避免同名列衝突(如 od.id as order_detail_id)
  • LEFT JOIN 保證無明細訂單也能查出
  • 查詢列順序無要求,但建議主表列在前,關聯表列在後

進階技巧

  1. 嵌套查詢:<association select="selectUserById" column="user_id"/> 按需加載,解決 N+1 問題需配合 fetchType="lazy"
  2. 鑒別器:<discriminator javaType="int" column="type"> 根據列值選擇不同 resultMap
  3. 自動映射:<resultMap autoMapping="true"> 簡單屬性自動匹配,複雜關聯手動配置

源碼地址

GitHub 完整項目

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved