MyBatis結(jié)果映射(ResultMap)的使用
在 MyBatis 中,結(jié)果映射(ResultMap) 是將數(shù)據(jù)庫查詢結(jié)果映射到 Java 對(duì)象的核心機(jī)制。它允許開發(fā)者靈活地定義數(shù)據(jù)庫表字段與 Java 對(duì)象屬性之間的映射關(guān)系,特別是當(dāng)字段和屬性名不一致,或者在處理復(fù)雜對(duì)象(如嵌套對(duì)象、集合)時(shí),ResultMap 提供了極大的便利。
1. 基本概念
在默認(rèn)情況下,如果數(shù)據(jù)庫字段名和 Java 對(duì)象的屬性名完全一致,MyBatis 可以自動(dòng)進(jìn)行映射。但是,當(dāng)字段名和屬性名不一致時(shí),或者涉及復(fù)雜的對(duì)象結(jié)構(gòu)時(shí),需要使用 ResultMap 來進(jìn)行精確的映射。
1.1 基本示例
假設(shè)有一個(gè)簡(jiǎn)單的數(shù)據(jù)庫表 users,結(jié)構(gòu)如下:
CREATE TABLE users (
id INT PRIMARY KEY,
user_name VARCHAR(50),
email VARCHAR(100)
);
以及一個(gè)對(duì)應(yīng)的 Java 類:
public class User {
private int id;
private String username;
private String email;
// getters and setters
}
在 SQL 查詢中,表的字段 user_name 和 Java 對(duì)象的 username 不匹配。這種情況下,可以通過 ResultMap 來手動(dòng)指定映射關(guān)系:
<resultMap id="userResultMap" type="com.example.model.User">
<id column="id" property="id" />
<result column="user_name" property="username" />
<result column="email" property="email" />
</resultMap>
在這里:
<id>標(biāo)簽用于指定主鍵字段映射到 Java 對(duì)象的id屬性。<result>標(biāo)簽用于定義普通字段的映射關(guān)系。
定義好 ResultMap 之后,可以在 SQL 查詢中引用它:
<select id="findUserById" resultMap="userResultMap">
SELECT id, user_name, email FROM users WHERE id = #{id}
</select>
通過這種方式,MyBatis 會(huì)將數(shù)據(jù)庫查詢結(jié)果自動(dòng)映射到 User 對(duì)象,即使數(shù)據(jù)庫字段與 Java 屬性名不匹配。
2. 字段映射類型
ResultMap 支持多種字段映射類型,以應(yīng)對(duì)不同的數(shù)據(jù)庫字段與 Java 屬性的映射需求。
2.1 ID 映射
<id> 標(biāo)簽用于指定數(shù)據(jù)庫表的主鍵字段,與 Java 對(duì)象中的主鍵屬性映射。例如:
<id column="id" property="id" />
這將數(shù)據(jù)庫表中的 id 字段映射到 Java 對(duì)象的 id 屬性。
2.2 常規(guī)字段映射
<result> 標(biāo)簽用于映射非主鍵字段。例如,將 user_name 映射到 username:
<result column="user_name" property="username" />
2.3 嵌套對(duì)象映射
ResultMap 支持將查詢結(jié)果中的某些字段映射到 Java 對(duì)象的嵌套對(duì)象中。例如,如果 User 類包含一個(gè) Address 對(duì)象,可以這樣映射:
public class User {
private int id;
private String username;
private String email;
private Address address;
// getters and setters
}
public class Address {
private String street;
private String city;
// getters and setters
}
假設(shè) users 表中有以下字段:
street:街道名稱city:城市名稱
可以通過 ResultMap 將這些字段映射到 User 對(duì)象中的 Address 屬性:
<resultMap id="userResultMap" type="com.example.model.User">
<id column="id" property="id" />
<result column="user_name" property="username" />
<result column="email" property="email" />
<association property="address" javaType="com.example.model.Address">
<result column="street" property="street" />
<result column="city" property="city" />
</association>
</resultMap>
這里使用 <association> 標(biāo)簽將 Address 類的字段與查詢結(jié)果中的 street 和 city 進(jìn)行映射。
2.4 集合映射
對(duì)于一對(duì)多的關(guān)系,MyBatis 提供了 <collection> 標(biāo)簽來處理集合映射。假設(shè)一個(gè) User 擁有多個(gè) Order,可以使用 <collection> 進(jìn)行映射:
public class User {
private int id;
private String username;
private List<Order> orders;
// getters and setters
}
public class Order {
private int id;
private String orderNumber;
// getters and setters
}
假設(shè) orders 表與 users 表通過 user_id 關(guān)聯(lián),可以使用以下 ResultMap:
<resultMap id="userResultMap" type="com.example.model.User">
<id column="id" property="id" />
<result column="user_name" property="username" />
<collection property="orders" ofType="com.example.model.Order">
<id column="order_id" property="id" />
<result column="order_number" property="orderNumber" />
</collection>
</resultMap>
這里的 <collection> 標(biāo)簽用于處理一對(duì)多關(guān)系,orders 列表中的每個(gè) Order 對(duì)象都由查詢結(jié)果中的 order_id 和 order_number 進(jìn)行填充。
3. 復(fù)雜映射:多對(duì)一與一對(duì)多
3.1 多對(duì)一映射
多對(duì)一關(guān)系通常通過 <association> 標(biāo)簽來處理。例如,Order 類中包含一個(gè) User 對(duì)象:
public class Order {
private int id;
private String orderNumber;
private User user;
// getters and setters
}
可以通過以下 ResultMap 將 Order 和 User 的關(guān)聯(lián)關(guān)系映射:
<resultMap id="orderResultMap" type="com.example.model.Order">
<id column="order_id" property="id" />
<result column="order_number" property="orderNumber" />
<association property="user" javaType="com.example.model.User">
<id column="user_id" property="id" />
<result column="user_name" property="username" />
<result column="email" property="email" />
</association>
</resultMap>
在這里,<association> 用于將查詢結(jié)果中的 user_id、user_name 和 email 字段映射到 Order 對(duì)象中的 User 屬性。
3.2 一對(duì)多映射
一對(duì)多關(guān)系通常通過 <collection> 標(biāo)簽來處理。假設(shè) User 類中包含多個(gè) Order,每個(gè)用戶可能有多個(gè)訂單,可以這樣配置:
<resultMap id="userResultMap" type="com.example.model.User">
<id column="id" property="id" />
<result column="user_name" property="username" />
<collection property="orders" ofType="com.example.model.Order">
<id column="order_id" property="id" />
<result column="order_number" property="orderNumber" />
</collection>
</resultMap>
在執(zhí)行查詢時(shí),MyBatis 會(huì)將每個(gè)用戶的訂單列表自動(dòng)映射到 User 對(duì)象中的 orders 集合中。
4. 嵌套查詢
有時(shí),由于性能問題,或者數(shù)據(jù)結(jié)構(gòu)過于復(fù)雜,直接使用嵌套結(jié)果映射可能并不合適。MyBatis 提供了嵌套查詢功能,允許在處理復(fù)雜對(duì)象時(shí),通過子查詢獲取關(guān)聯(lián)對(duì)象的數(shù)據(jù)。
嵌套查詢示例
假設(shè)我們有以下結(jié)構(gòu),Order 類中包含 User 對(duì)象,可以使用嵌套查詢:
<resultMap id="orderResultMap" type="com.example.model.Order">
<id column="order_id" property="id" />
<result column="order_number" property="orderNumber" />
<association property="user" javaType="com.example.model.User"
select="findUserById" column="user_id" />
</resultMap>
<select id="findUserById" resultType="com.example.model.User">
SELECT id, user_name, email FROM users WHERE id = #{id}
</select>
在這個(gè)例子中,<association> 標(biāo)簽中的 select 屬性用于指定一個(gè)單獨(dú)的查詢來獲取關(guān)聯(lián)對(duì)象(User),而不是直接從主查詢中獲取。
5. 自定義類型轉(zhuǎn)換
在某些情況下,數(shù)據(jù)庫中的字段類型可能與 Java 對(duì)象屬性類型不一致。MyBatis 提供了類型處理器(TypeHandler),用于自定義數(shù)據(jù)庫類型與 Java 類型之間的轉(zhuǎn)換。
自定義 TypeHandler 示例
假設(shè)數(shù)據(jù)庫中的性別字段是 INT 類型(0 表示男性,`
1表示女性),而 Java 類中的屬性為String 類型(“Male"和"Female”),可以通過自定義 TypeHandler` 實(shí)現(xiàn)類型轉(zhuǎn)換:
public class GenderTypeHandler extends BaseTypeHandler<String> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setInt(i, "Male".equals(parameter) ? 0 : 1);
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
int gender = rs.getInt(columnName);
return gender == 0 ? "Male" : "Female";
}
// 其他重載方法省略
}
在 MyBatis 配置中注冊(cè)自定義 TypeHandler:
<typeHandlers>
<typeHandler javaType="java.lang.String" jdbcType="INTEGER" handler="com.example.handler.GenderTypeHandler"/>
</typeHandlers>
這樣,在處理性別字段時(shí),MyBatis 會(huì)自動(dòng)使用自定義的類型轉(zhuǎn)換邏輯。
結(jié)論
MyBatis 的 ResultMap 是一種強(qiáng)大的結(jié)果映射機(jī)制,允許開發(fā)者靈活地將數(shù)據(jù)庫查詢結(jié)果與 Java 對(duì)象進(jìn)行映射。通過使用 ResultMap,可以處理字段名不一致、嵌套對(duì)象、一對(duì)多、多對(duì)一等復(fù)雜映射場(chǎng)景。結(jié)合自定義類型轉(zhuǎn)換和嵌套查詢,MyBatis 提供了高度靈活的持久化解決方案,能夠滿足復(fù)雜的數(shù)據(jù)映射需求。
到此這篇關(guān)于MyBatis結(jié)果映射(ResultMap)的使用的文章就介紹到這了,更多相關(guān)MyBatis結(jié)果映射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis延遲加載、關(guān)聯(lián)查詢與結(jié)果映射的實(shí)現(xiàn)原理解析
- 深度分析MybatisPlus查詢結(jié)果映射失敗@TableField失效解決辦法
- MyBatis 結(jié)果映射的兩種方式
- MyBatis動(dòng)態(tài)SQL、模糊查詢與結(jié)果映射操作過程
- Java中MyBatis的結(jié)果映射詳解
- MyBatis中的SQL映射文件配置結(jié)果映射的操作指南
- 關(guān)于MyBatis結(jié)果映射的實(shí)例總結(jié)
- 基于mybatis查詢結(jié)果映射不到對(duì)象的處理
- MyBatis 結(jié)果映射的幾種實(shí)現(xiàn)方式
相關(guān)文章
SpringBoot自動(dòng)配置深入探究實(shí)現(xiàn)原理
在springboot的啟動(dòng)類中可以看到@SpringBootApplication注解,它是SpringBoot的核心注解,也是一個(gè)組合注解。其中@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三個(gè)注解尤為重要。今天我們就來淺析這三個(gè)注解的含義2022-08-08
Springboot 接口對(duì)接文件及對(duì)象的操作方法
這篇文章主要介紹了Springboot 接口對(duì)接文件及對(duì)象的操作,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
JAVA實(shí)現(xiàn)SOCKET多客戶端通信的案例
這篇文章主要介紹了JAVA實(shí)現(xiàn)SOCKET多客戶端通信的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12
java JVM原理與常識(shí)知識(shí)點(diǎn)
在本文中小編給大家分享的是關(guān)于java的JVM原理和java常識(shí),有興趣的朋友們可以學(xué)習(xí)下2018-12-12

