亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MyBatis 結(jié)果映射的幾種實(shí)現(xiàn)方式

 更新時(shí)間:2025年09月07日 09:51:17   作者:碼熔burning  
本文主要介紹了MyBatis中的結(jié)果映射機(jī)制,包括映射方式及其在處理關(guān)聯(lián)關(guān)系中的高級(jí)應(yīng)用,具有一定的參考價(jià)值,感興趣的可以了解一下

一、 什么是結(jié)果映射? ??

在我們的 Java 應(yīng)用程序中,數(shù)據(jù)通常以對(duì)象(JavaBeans/POJOs)的形式存在。然而,關(guān)系型數(shù)據(jù)庫(kù)是以行和列的形式存儲(chǔ)數(shù)據(jù)。當(dāng)我們從數(shù)據(jù)庫(kù)查詢數(shù)據(jù)時(shí),得到的是一個(gè)包含多行多列的結(jié)果集(ResultSet)。

結(jié)果映射(Result Mapping) 就是 MyBatis 中定義如何將數(shù)據(jù)庫(kù)查詢結(jié)果集中的列(Columns)映射到 Java 對(duì)象的屬性(Properties)上的規(guī)則和過(guò)程。它是解決數(shù)據(jù)庫(kù)中心的數(shù)據(jù)表示(表結(jié)構(gòu))與應(yīng)用程序中心的對(duì)象模型(類結(jié)構(gòu))之間“阻抗失配”問(wèn)題的核心機(jī)制。

簡(jiǎn)單來(lái)說(shuō): 告訴 MyBatis,數(shù)據(jù)庫(kù)查出來(lái)的 user_id 這一列的值,應(yīng)該賦給 User 這個(gè) Java 類的 userId 這個(gè)屬性。

二、 為何需要結(jié)果映射? ??

  1. 命名差異:數(shù)據(jù)庫(kù)列名常用下劃線命名法(snake_case,如 order_id),而 Java 屬性常用駝峰命名法(camelCase,如 orderId)。需要轉(zhuǎn)換。
  2. 類型轉(zhuǎn)換 ??:數(shù)據(jù)庫(kù)類型(如 VARCHAR, TIMESTAMP, NUMBER)需要轉(zhuǎn)換為相應(yīng)的 Java 類型(如 String, java.util.Date, Integer, BigDecimal)。
  3. 復(fù)雜關(guān)系:實(shí)際應(yīng)用中,數(shù)據(jù)往往不是扁平的。一個(gè)對(duì)象可能包含另一個(gè)對(duì)象(一對(duì)一/多對(duì)一),或者包含一個(gè)對(duì)象集合(一對(duì)多)。需要機(jī)制來(lái)處理這些關(guān)聯(lián)。
  4. 顯式控制 ??:有時(shí)自動(dòng)映射無(wú)法滿足需求,需要更精細(xì)地控制映射過(guò)程,例如列名和屬性名差異很大,或需要使用自定義的類型處理器(TypeHandler)。

三、 如何映射?(基礎(chǔ))?

MyBatis 提供了多種方式進(jìn)行結(jié)果映射:

1、 別名映射 ??

這是最直接的方式,在 SQL 語(yǔ)句中使用 AS 關(guān)鍵字為查詢的列指定別名,讓別名與 Java 對(duì)象的屬性名完全一致。

Java Bean (User.java)

public class User {
    private Integer userId;
    private String userName;
    private String userEmail;
    // getters and setters...
}

Mapper XML (UserMapper.xml)

<select id="findUserById" resultType="com.yourcompany.domain.User">
  SELECT
      user_id   AS userId,  -- 使用 AS 將列名映射到屬性名
      user_name AS userName,
      email     AS userEmail -- 列名和屬性名不一致時(shí)必須用 AS
  FROM users
  WHERE user_id = #{id}
</select>
  • 優(yōu)點(diǎn):非常明確,SQL 本身就定義了映射關(guān)系。
  • 缺點(diǎn):SQL 語(yǔ)句會(huì)變得冗長(zhǎng),尤其當(dāng)字段很多時(shí)。SQL 摻雜了部分映射邏輯。

2、 駝峰命名自動(dòng)映射??

這是 MyBatis 提供的一個(gè)便捷功能。開(kāi)啟后,MyBatis 會(huì)自動(dòng)嘗試將下劃線命名法的列(column_name)映射到駝峰命名法的屬性(columnName)。

Java Bean (User.java) - 同上

Mapper XML (UserMapper.xml)

<select id="findUserById" resultType="com.yourcompany.domain.User">
  SELECT
      user_id,   -- 無(wú)需 AS
      user_name,
      email     -- 如果屬性名是 email,也能自動(dòng)映射
  FROM users
  WHERE user_id = #{id}
</select>

(注意:如果 Java 屬性名不是標(biāo)準(zhǔn)的駝峰轉(zhuǎn)換,駝峰映射也無(wú)法自動(dòng)處理)

如何開(kāi)啟?

MyBatis 配置文件 (mybatis-config.xml):

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

Spring Boot 配置文件 (application.propertiesapplication.yml):

# application.properties
mybatis.configuration.map-underscore-to-camel-case=true
# application.yml
mybatis:
  configuration:
    map-underscore-to-camel-case: true

通過(guò) Java 配置 (如 Spring):

@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    // ... 其他配置
    org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
    configuration.setMapUnderscoreToCamelCase(true); // 開(kāi)啟駝峰映射
    factoryBean.setConfiguration(configuration);
    // ... 其他配置
    return factoryBean.getObject();
}
  • 優(yōu)點(diǎn):保持 SQL 簡(jiǎn)潔 ?,配置一次全局生效,是目前推薦的主流簡(jiǎn)單映射方式。
  • 缺點(diǎn):需要配置開(kāi)啟;對(duì)于非標(biāo)準(zhǔn)駝峰映射的場(chǎng)景無(wú)能為力。

3、 resultMap 顯式映射 ???

當(dāng)自動(dòng)映射(包括駝峰)無(wú)法滿足需求,或者需要處理復(fù)雜類型、關(guān)聯(lián)查詢時(shí),resultMap 是最強(qiáng)大、最靈活的武器。它允許你顯式地、精確地定義列與屬性之間的映射關(guān)系。

Java Bean (User.java) - 同上

Mapper XML (UserMapper.xml)

定義 <resultMap>:

<resultMap id="userResultMap" type="com.yourcompany.domain.User">
    <!-- <id> 標(biāo)簽用于映射主鍵字段,有助于 MyBatis 性能優(yōu)化 -->
    <id property="userId" column="user_id" />
    <!-- <result> 標(biāo)簽用于映射普通字段 -->
    <result property="userName" column="user_name"/>
    <result property="userEmail" column="email"/>
    <!-- 可以指定 javaType 和 jdbcType,通常 MyBatis 能自動(dòng)推斷 -->
    <!-- <result property="status" column="user_status" javaType="java.lang.Integer" jdbcType="INTEGER"/> -->
</resultMap>

<select> 標(biāo)簽中使用 resultMap 屬性引用:

<select id="findUserById" resultMap="userResultMap">
  SELECT user_id, user_name, email FROM users WHERE user_id = #{id}
</select>
  • <resultMap> 屬性:

    • id: 在當(dāng)前 Mapper XML 命名空間內(nèi)的唯一標(biāo)識(shí)符。
    • type: 映射的目標(biāo) Java 類的完全限定名或 MyBatis 配置的別名。
  • 子標(biāo)簽 <id><result> 屬性:

    • property: Java 對(duì)象的屬性名。
    • column: SQL 查詢結(jié)果集中的列名(或別名)。
    • javaType: Java 屬性的完整類名或別名(通??墒÷裕?。
    • jdbcType: 數(shù)據(jù)庫(kù)列的 JDBC 類型(枚舉 org.apache.ibatis.type.JdbcType)。
    • typeHandler: 指定自定義的類型處理器。
  • 優(yōu)點(diǎn):控制力最強(qiáng) ??!能處理各種復(fù)雜映射場(chǎng)景,是實(shí)現(xiàn)高級(jí)映射的基礎(chǔ)。代碼更清晰,SQL 保持純凈。

  • 缺點(diǎn):配置相對(duì)繁瑣,增加了 XML 的代碼量。

四、 高級(jí)結(jié)果映射 (處理關(guān)聯(lián)關(guān)系) ??

當(dāng)查詢結(jié)果需要映射到包含其他對(duì)象或?qū)ο蠹系膹?fù)雜 Java 對(duì)象時(shí),就需要使用 resultMap 的高級(jí)特性:<association><collection>

場(chǎng)景設(shè)定:

  • 實(shí)體類:
    • Department.java: 包含 id, name 屬性。
    • Employee.java: 包含 id, name, email, department (Department 對(duì)象), departmentId (Integer)。
  • 數(shù)據(jù)庫(kù)表:
    • departments (id PK, dept_name)
    • employees (id PK, emp_name, emp_email, dept_id FK references departments.id)

1、<association>(處理 “有一個(gè)” 關(guān)系 - To-One) ????

用于映射一個(gè)對(duì)象中包含的另一個(gè)對(duì)象,通常對(duì)應(yīng)數(shù)據(jù)庫(kù)中的 一對(duì)一多對(duì)一 關(guān)系。

兩種主要實(shí)現(xiàn)方式:

1. 嵌套 Select 查詢 (Nested Select)

  • 思路: 先查詢主對(duì)象(Employee),然后根據(jù)外鍵(dept_id),再執(zhí)行一個(gè)單獨(dú)的 SQL 查詢獲取關(guān)聯(lián)對(duì)象(Department)。
  • Mapper XML:
    <select id="findDepartmentById" resultType="com.yourcompany.domain.Department">...</select>
    
    <resultMap id="employeeWithDeptSelectMap" type="com.yourcompany.domain.Employee">
        <id property="id" column="id"/>
        <result property="name" column="emp_name"/>
        <!-- association: 映射 department 屬性 -->
        <association property="department" javaType="com.yourcompany.domain.Department"
                     column="dept_id"        select="findDepartmentById" />
                     <!-- column: 傳遞給 select 查詢的參數(shù)列 -->
                     <!-- select: 指定用于查詢關(guān)聯(lián)對(duì)象的 select 語(yǔ)句 ID -->
                     <!-- fetchType="lazy": 可配置懶加載 -->
    </resultMap>
    
    <select id="findEmployeeByIdWithDeptSelect" resultMap="employeeWithDeptSelectMap">...</select>
    
  • 優(yōu)點(diǎn): 簡(jiǎn)單直觀,SQL 語(yǔ)句分離,支持懶加載。
  • 缺點(diǎn): N+1 查詢問(wèn)題!性能可能很差 ??,通常不推薦使用 ?。

2. 嵌套結(jié)果映射 (Nested Result Map) ?

  • 思路: 使用 SQL 的 JOIN 操作一次性查詢出所有需要的數(shù)據(jù),然后在 resultMap 中定義嵌套結(jié)構(gòu)來(lái)映射連接后的結(jié)果。
  • Mapper XML:
    <resultMap id="employeeWithDeptNestedMap" type="com.yourcompany.domain.Employee">
        <id property="id" column="emp_id"/>
        <result property="name" column="emp_name"/>
        <result property="departmentId" column="dept_id"/>
    
        <!-- association: 映射 department 屬性 -->
        <association property="department" javaType="com.yourcompany.domain.Department">
            <!-- 嵌套定義 Department 的映射規(guī)則 -->
            <id property="id" column="dept_id"/>
            <result property="name" column="dept_name"/>
        </association>
    </resultMap>
    
    <select id="findEmployeeByIdWithDeptNested" resultMap="employeeWithDeptNestedMap">
        SELECT
            e.id AS emp_id, e.emp_name, e.emp_email, e.dept_id,
            d.id AS dept_id, d.dept_name -- 查詢關(guān)聯(lián)表的列,注意別名
        FROM employees e
        LEFT JOIN departments d ON e.dept_id = d.id
        WHERE e.id = #{empId}
    </select>
    
  • 優(yōu)點(diǎn): 性能好 ??,只需執(zhí)行一次 SQL 查詢。結(jié)構(gòu)清晰。這是處理關(guān)聯(lián)關(guān)系推薦的方式 ?。
  • 缺點(diǎn): SQL 語(yǔ)句可能因 JOIN 變得復(fù)雜;不支持懶加載(但通常性能好就不需要了)。

2、<collection>(處理 “有很多” 關(guān)系 - To-Many) ????

用于映射一個(gè)對(duì)象中包含的對(duì)象集合,通常對(duì)應(yīng)數(shù)據(jù)庫(kù)中的 一對(duì)多 關(guān)系。

同樣有兩種實(shí)現(xiàn)方式:

1. 嵌套 Select 查詢 (Nested Select)

  • 思路: 先查詢主對(duì)象(Department),然后根據(jù)主鍵(id),再執(zhí)行一個(gè)單獨(dú)的 SQL 查詢獲取關(guān)聯(lián)的對(duì)象集合(List)。
  • Java Bean (Department.java): (需要有 List<Employee> employees; 屬性)
  • Mapper XML:
    <select id="findEmployeesByDeptId" resultType="com.yourcompany.domain.Employee">...</select>
    
    <resultMap id="deptWithEmployeesSelectMap" type="com.yourcompany.domain.Department">
        <id property="id" column="id"/>
        <result property="name" column="dept_name"/>
        <!-- collection: 映射 employees 集合屬性 -->
        <collection property="employees" ofType="com.yourcompany.domain.Employee"
                    column="id"           select="findEmployeesByDeptId" />
                    <!-- column: 傳遞給 select 查詢的參數(shù)列 -->
                    <!-- select: 指定用于查詢關(guān)聯(lián)集合的 select 語(yǔ)句 ID -->
                    <!-- ofType: 指定集合中元素的類型 -->
                    <!-- fetchType="lazy": 支持懶加載 -->
    </resultMap>
    
    <select id="findDeptByIdWithEmployeesSelect" resultMap="deptWithEmployeesSelectMap">...</select>
    
  • 優(yōu)點(diǎn): 簡(jiǎn)單直觀,SQL 分離,支持懶加載。
  • 缺點(diǎn): N+1 查詢問(wèn)題!性能問(wèn)題嚴(yán)重 ??,通常不推薦使用 ?。

2. 嵌套結(jié)果映射 (Nested Result Map) ?

  • 思路: 使用 SQL 的 LEFT JOIN 一次性查詢出部門(mén)及其所有員工的信息。MyBatis 的 resultMap 機(jī)制能智能地將重復(fù)的主對(duì)象信息合并,并將關(guān)聯(lián)的從對(duì)象信息收集到集合中。
  • Mapper XML:
    <resultMap id="employeeBaseMap" type="com.yourcompany.domain.Employee">...</resultMap>
    
    <resultMap id="deptWithEmployeesNestedMap" type="com.yourcompany.domain.Department">
        <id property="id" column="dept_id"/> <!-- 部門(mén) ID 是主鍵 -->
        <result property="name" column="dept_name"/>
        <!-- collection: 映射 employees 集合屬性 -->
        <collection property="employees" ofType="com.yourcompany.domain.Employee"
                    resultMap="employeeBaseMap" />
                    <!-- ofType: 指定集合元素類型 -->
                    <!-- resultMap: 引用 Employee resultMap 來(lái)映射集合中的每個(gè)對(duì)象 -->
                    <!-- 或者可以直接在 collection 內(nèi)部定義映射規(guī)則 -->
    </resultMap>
    
    <select id="findDeptByIdWithEmployeesNested" resultMap="deptWithEmployeesNestedMap">
        SELECT
            d.id AS dept_id, d.dept_name,
            e.id AS emp_id, e.emp_name, e.emp_email
        FROM departments d
        LEFT JOIN employees e ON d.id = e.dept_id
        WHERE d.id = #{deptId}
    </select>
    
  • 優(yōu)點(diǎn): 性能好 ??,只需一次 SQL 查詢。MyBatis 自動(dòng)處理結(jié)果聚合。映射邏輯集中。這是處理一對(duì)多關(guān)系推薦的方式 ?。
  • 缺點(diǎn): SQL 語(yǔ)句可能較復(fù)雜;返回的數(shù)據(jù)量可能較大(主表信息會(huì)重復(fù))。

五、 選擇哪種映射方式? ??

  • 簡(jiǎn)單場(chǎng)景(列名與屬性名一致或符合駝峰規(guī)則):優(yōu)先使用駝峰自動(dòng)映射 ??。
  • 列名與屬性名不一致/不規(guī)則:少數(shù)幾個(gè)字段用 SQL 別名 AS ??;較多或想保持 SQL 純凈,使用 resultMap ???。
  • 需要類型轉(zhuǎn)換/自定義 TypeHandler:必須使用 resultMap ??。
  • 處理一對(duì)一/多對(duì)一/一對(duì)多關(guān)聯(lián)關(guān)系:必須使用 resultMap<association><collection> ??。強(qiáng)烈推薦使用 嵌套結(jié)果映射 (Nested Result Map) 方式(基于 JOIN)?,避免 N+1 問(wèn)題。只有在明確需要懶加載且能接受其潛在性能影響時(shí),才考慮嵌套 Select。

六、 總結(jié) ??

MyBatis 的結(jié)果映射機(jī)制是其強(qiáng)大功能的核心之一。從簡(jiǎn)單的別名、駝峰自動(dòng)映射到強(qiáng)大的 resultMap(包括處理復(fù)雜關(guān)聯(lián)的 <association><collection>),它提供了靈活多樣的手段來(lái)連接數(shù)據(jù)庫(kù)表結(jié)構(gòu)和 Java 對(duì)象模型。理解并熟練運(yùn)用這些映射方式,特別是掌握 resultMap 的高級(jí)用法并優(yōu)先選擇嵌套結(jié)果映射來(lái)處理關(guān)聯(lián),對(duì)于編寫(xiě)高效、可維護(hù)的 MyBatis 應(yīng)用至關(guān)重要。

到此這篇關(guān)于MyBatis 結(jié)果映射的幾種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)MyBatis 結(jié)果映射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java世界時(shí)區(qū)自動(dòng)計(jì)算及時(shí)間生成方法詳解

    Java世界時(shí)區(qū)自動(dòng)計(jì)算及時(shí)間生成方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java中世界時(shí)區(qū)自動(dòng)計(jì)算及時(shí)間生成的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • 以Json形式的數(shù)據(jù)格式實(shí)現(xiàn)JMeter參數(shù)化

    以Json形式的數(shù)據(jù)格式實(shí)現(xiàn)JMeter參數(shù)化

    本文以小項(xiàng)目學(xué)院管理系統(tǒng)為例,給大家分享以Json形式的數(shù)據(jù)格式實(shí)現(xiàn)JMeter參數(shù)化的相關(guān)知識(shí),包括添加元件操作步驟及使用用戶參數(shù)組件實(shí)現(xiàn)參數(shù)化的方法,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Javaweb監(jiān)聽(tīng)器實(shí)例之統(tǒng)計(jì)在線人數(shù)

    Javaweb監(jiān)聽(tīng)器實(shí)例之統(tǒng)計(jì)在線人數(shù)

    這篇文章主要為大家詳細(xì)介紹了Javaweb監(jiān)聽(tīng)器實(shí)例之統(tǒng)計(jì)在線人數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • mybatis如何使用truncate清空表

    mybatis如何使用truncate清空表

    這篇文章主要介紹了mybatis如何使用truncate清空表,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • springBoot啟動(dòng)輸出三行日志控制臺(tái)自動(dòng)停止操作

    springBoot啟動(dòng)輸出三行日志控制臺(tái)自動(dòng)停止操作

    這篇文章主要介紹了springBoot啟動(dòng)輸出三行日志控制臺(tái)自動(dòng)停止操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Spring中為bean指定InitMethod和DestroyMethod的執(zhí)行方法

    Spring中為bean指定InitMethod和DestroyMethod的執(zhí)行方法

    在Spring中,那些組成應(yīng)用程序的主體及由Spring IoC容器所管理的對(duì)象,被稱之為bean,接下來(lái)通過(guò)本文給大家介紹Spring中為bean指定InitMethod和DestroyMethod的執(zhí)行方法,感興趣的朋友一起看看吧
    2021-11-11
  • Java日期毫秒值和常見(jiàn)日期時(shí)間格式相互轉(zhuǎn)換方法

    Java日期毫秒值和常見(jiàn)日期時(shí)間格式相互轉(zhuǎn)換方法

    這篇文章主要給大家介紹了關(guān)于Java日期毫秒值和常見(jiàn)日期時(shí)間格式相互轉(zhuǎn)換的相關(guān)資料,在Java的日常開(kāi)發(fā)中,會(huì)隨時(shí)遇到需要對(duì)時(shí)間處理的情況,文中給出了詳細(xì)的示例代碼,需要的朋友可以參考下
    2023-07-07
  • Java 繼承與多態(tài)的深入理解

    Java 繼承與多態(tài)的深入理解

    這篇文章主要介紹了Java 繼承與多態(tài)的深入理解的相關(guān)資料,子類繼承父類的特征和行為,使得子類具有父類的各種屬性和方法。或子類從父類繼承方法,使得子類具有父類相同的行為,需要的朋友可以參考下
    2017-08-08
  • java中的異或問(wèn)題代碼解析

    java中的異或問(wèn)題代碼解析

    這篇文章主要介紹了java中的異或問(wèn)題代碼解析,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Springboot整合Urule的方法步驟

    Springboot整合Urule的方法步驟

    這篇文章主要介紹了Springboot整合Urule的方法步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-05-05

最新評(píng)論