mybatis中resultMap的association及collectio的使用詳解
1.reusltmap的說明
resultmap定義了數(shù)據(jù)庫的結(jié)果映射到j(luò)ava對象的規(guī)則,resultmap包含4個屬性:
id: ResultMap 的唯一標(biāo)識type: 映射到的 Java 類型(全限定類名或別名)extends: 繼承另一個 ResultMapautoMapping: 是否開啟自動映射(true/false)
前三個比較常用
resultmap包含以下子元素,并且子元素是有定義順序的,如下:
<constructor>(可選)<id>(至少一個)<result>(零個或多個)<association>(零個或多個)<collection>(零個或多個)<discriminator>(可選)
必須遵循上述順序,如果順序不正確,MyBatis 在解析 XML 時會拋出異常
<id>元素必須出現(xiàn)在<result>元素之前- 如果使用
<constructor>,它必須是第一個元素 <discriminator>必須是最后一個元素(如果存在)
2.association的使用
<association> 是 MyBatis 中用于處理一對一關(guān)聯(lián)關(guān)系的元素,它可以將查詢結(jié)果中的一部分?jǐn)?shù)據(jù)映射到一個復(fù)雜的關(guān)聯(lián)對象中。
在實際開發(fā)中,如果想一次查詢兩張表的數(shù)據(jù),不想通過兩次查詢的方式,而是想一次查詢出來,可以通過兩張表關(guān)聯(lián)將表A和表B的數(shù)據(jù)都查詢出來
| 屬性名 | 說明 |
|---|---|
| property | Java對象中的屬性名 |
| javaType | 關(guān)聯(lián)對象的Java類型(全限定類名或別名) |
| resultMap | 引用外部定義的resultMap |
| column | 傳遞給嵌套查詢的列名(可以是多個列:column="{prop1=col1,prop2=col2}") |
| select | 另一個映射語句的ID,用于嵌套查詢 |
| fetchType | 覆蓋全局的延遲加載設(shè)置(lazy/eager) |
| autoMapping | 是否啟用自動映射(true/false) |
<!-- 一對一關(guān)聯(lián)映射示例 -->
<resultMap id="UserWithDeptMap" type="com.example.User">
<!-- 用戶表字段映射 -->
<id column="user_id" property="id" jdbcType="BIGINT"/>
<result column="user_name" property="name" jdbcType="VARCHAR"/>
<result column="user_age" property="age" jdbcType="INTEGER"/>
<!-- 一對一關(guān)聯(lián) department 對象 -->
<association property="department" javaType="com.example.Department">
<id column="dept_id" property="id" jdbcType="BIGINT"/>
<result column="dept_name" property="deptName" jdbcType="VARCHAR"/>
<result column="dept_location" property="location" jdbcType="VARCHAR"/>
</association>
</resultMap><select id="selectUserWithDepartment" resultMap="UserWithDeptMap">
SELECT
u.id AS user_id,
u.name AS user_name,
u.age AS user_age,
d.id AS dept_id,
d.name AS dept_name,
d.location AS dept_location
FROM
user u
LEFT JOIN
department d ON u.dept_id = d.id
WHERE
u.id = #{userId}
</select>package com.example;
public class User {
private Long id; // 對應(yīng) user_id 字段
private String name; // 對應(yīng) user_name 字段
private Integer age; // 對應(yīng) user_age 字段
private Department department; // 一對一關(guān)聯(lián)對象
// 必須的 getter 和 setter 方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}package com.example;
public class Department {
private Long id; // 對應(yīng) dept_id 字段
private String deptName; // 對應(yīng) dept_name 字段
private String location; // 對應(yīng) dept_location 字段
// 必須的 getter 和 setter 方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}使用關(guān)聯(lián)查詢只需要指定以下兩個屬性即可
配置項 | 作用 |
property="department" | 指定 User 類中關(guān)聯(lián)屬性的名稱(需與字段名一致)。 |
javaType | 指定關(guān)聯(lián)對象的完整類名(可省略,MyBatis 通常能自動推斷)。 |
3.collection的使用
<collection> 是 MyBatis 中用于處理一對多關(guān)聯(lián)關(guān)系的核心元素,它能夠?qū)⒉樵兘Y(jié)果中的多條記錄映射到一個集合屬性中(如 List、Set 等)
| 屬性名 | 是否必填 | 說明 |
|---|---|---|
| property | 必填 | Java對象中的集合屬性名稱 |
| ofType | 條件必填 | 集合中元素的Java類型(當(dāng)不使用resultMap時必填) |
| column | 條件必填 | 傳遞給嵌套查詢的列名(使用select時必填) |
| select | 可選 | 另一個映射語句的ID,用于嵌套查詢 |
| fetchType | 可選 | 加載方式(lazy/eager),覆蓋全局配置 |
| javaType | 可選 | 集合的Java類型(如ArrayList、HashSet等) |
| resultMap | 可選 | 引用外部定義的resultMap |
| autoMapping | 可選 | 是否啟用自動映射(true/false) |
<resultMap id="UserWithOrdersMap" type="com.example.model.User">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<result property="age" column="user_age"/>
<!-- 一對多關(guān)聯(lián)訂單集合 -->
<collection property="orders" ofType="com.example.model.Order">
<id property="id" column="order_id"/>
<result property="orderNo" column="order_no"/>
<result property="amount" column="order_amount"/>
<result property="userId" column="user_id"/>
</collection>
</resultMap>
<select id="selectUserWithOrders" resultMap="UserWithOrdersMap">
SELECT
u.id as user_id,
u.name as user_name,
u.age as user_age,
o.id as order_id,
o.order_no as order_no,
o.amount as order_amount,
o.user_id
FROM user u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.id = #{userId}
</select>package com.example.model;
import java.util.List;
public class User {
private Long id;
private String name;
private Integer age;
private List<Order> orders; // 一對多關(guān)聯(lián)的訂單集合
// getters and setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
}package com.example.model;
public class Order {
private Long id;
private String orderNo;
private Double amount;
private Long userId; // 外鍵,關(guān)聯(lián)用戶ID
// getters and setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
}使用關(guān)聯(lián)查詢只需要指定以下兩個屬性即可
| 屬性名 | 是否必填 | 說明 |
|---|---|---|
| property | 必填 | Java對象中的集合屬性名稱 |
| ofType | 條件必填 | 集合中元素的Java類型(當(dāng)不使用resultMap時必填) |
4.總結(jié)
①在 MyBatis 的 <resultMap> 中,如果使用 <association> 或 <collection> 映射關(guān)聯(lián)關(guān)系,必須為父對象(主對象)至少定義一個 <id> 屬性
MyBatis 使用 <id> 來唯一標(biāo)識一個對象,用于:
- 一級/二級緩存的鍵值
- 解決嵌套映射中的循環(huán)引用問題
- 避免重復(fù)創(chuàng)建相同對象(性能優(yōu)化)
關(guān)聯(lián)映射的依賴:
- 當(dāng)存在
<association>或<collection>時,MyBatis 需要通過父對象的<id>來管理關(guān)聯(lián)對象的加載和綁定。
②association及collection中的id屬性是可選的,但建議加上,它用于避免重復(fù)子對象(例如 JOIN 導(dǎo)致重復(fù)數(shù)據(jù)時去重)。
如果子對象中定義了 <id> 屬性,MyBatis 會對 <collection> 中的重復(fù)子對象進(jìn)行去重。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java Map轉(zhuǎn)Object與Object轉(zhuǎn)Map實現(xiàn)代碼
這篇文章主要介紹了 java Map轉(zhuǎn)Object與Object轉(zhuǎn)Map實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02
Mybatis中使用updateBatch進(jìn)行批量更新
這篇文章主要介紹了Mybatis中使用updateBatch進(jìn)行批量更新的相關(guān)資料,有逐條更新,sql批量更新等,具體實例代碼大家參考下本文2018-04-04
Java實現(xiàn)超大Excel文件解析(XSSF,SXSSF,easyExcel)
這篇文章主要為大家詳細(xì)介紹了如何利用Java語言實現(xiàn)超大Excel文件解析(XSSF,SXSSF,easyExcel)以及速度的對比,感興趣的可以了解一下2022-07-07
Springboot基于websocket實現(xiàn)簡單在線聊天功能
這篇文章主要介紹了Springboot基于websocket實現(xiàn)簡單在線聊天功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06
怎么用idea創(chuàng)建一個SpringBoot項目
本文介紹了在IDEA中創(chuàng)建Spring Boot項目的步驟,包括環(huán)境準(zhǔn)備(JDK 1.8+、Maven 3.2.5+)、使用Spring Initializr生成項目結(jié)構(gòu)、配置啟動端口、創(chuàng)建控制器及測試方法,強(qiáng)調(diào)依賴管理與注解處理,感興趣的朋友一起看看吧2025-06-06
java設(shè)計模式之建造者模式學(xué)習(xí)
建造者模式(Builder Pattern)主要用于“分步驟構(gòu)建一個復(fù)雜的對象”,在這其中“分步驟”是一個穩(wěn)定的算法,下面給出了詳細(xì)的示例2014-01-01
springboot集成nacos無法動態(tài)獲取nacos配置的問題
這篇文章主要介紹了springboot集成nacos無法動態(tài)獲取nacos配置的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
Spring 處理 HTTP 請求參數(shù)注解的操作方法
這篇文章主要介紹了Spring 處理 HTTP 請求參數(shù)注解的操作方法,本文通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友參考下吧2024-04-04
idea社區(qū)版如何設(shè)置vm?options
這篇文章主要介紹了idea社區(qū)版如何設(shè)置vm?options問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09

