欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis 數(shù)據(jù)封裝全攻略(告別空值與映射混亂問題)

 更新時間:2025年09月28日 11:39:21   作者:lsp程序員010  
本文系統(tǒng)介紹MyBatis數(shù)據(jù)封裝的常見問題及解決方案,涵蓋resultType、resultMap、駝峰轉(zhuǎn)換、嵌套處理、懶加載等核心機制,并推薦MyBatis-Plus簡化開發(fā),提升效率與可維護性,感興趣的朋友跟隨小編一起看看吧

MyBatis 數(shù)據(jù)封裝全攻略:告別空值與映射混亂

在日常開發(fā)中,使用 MyBatis 進行數(shù)據(jù)庫操作時,你是否經(jīng)常遇到以下問題?

  • 查詢結(jié)果部分字段為 null,導(dǎo)致前端顯示異常?
  • 多表聯(lián)查時對象嵌套關(guān)系映射失?。?/li>
  • 字段名和屬性名不一致,結(jié)果集無法正確賦值?
  • 集合類型(如 List)屬性始終為空?
  • 使用 resultType 返回 Map 時結(jié)構(gòu)混亂、不易維護?

這些問題本質(zhì)上都是 數(shù)據(jù)封裝(Result Mapping) 的問題。本文將系統(tǒng)性地為你梳理 MyBatis 中數(shù)據(jù)封裝的核心機制,并提供最佳實踐方案,助你徹底解決封裝難題!

一、MyBatis 數(shù)據(jù)封裝的兩種方式

1. resultType —— 簡單粗暴

適用于字段名與 Java 屬性名完全匹配的情況。

<select id="getUserById" resultType="com.example.User">
    SELECT id, username, email FROM user WHERE id = #{id}
</select>

? 優(yōu)點:簡潔、易用
? 缺點:無法處理駝峰命名、多表關(guān)聯(lián)、嵌套對象等復(fù)雜場景

?? 注意:若數(shù)據(jù)庫字段是 user_name,而 Java 屬性是 userName,則不會自動映射!

二、開啟駝峰命名轉(zhuǎn)換(推薦基礎(chǔ)配置)

mybatis-config.xml 或 Spring Boot 配置中開啟:

# application.yml (Spring Boot)
mybatis:
  configuration:
    map-underscore-to-camel-case: true

或 XML 配置:

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

開啟后,user_nameuserName,create_timecreateTime 自動映射。

三、resultMap —— 精準控制映射關(guān)系

resultType 無法滿足需求時,必須使用 <resultMap>。

基礎(chǔ)字段映射

<resultMap id="UserResultMap" type="com.example.User">
    <id property="id" column="user_id"/> <!-- 主鍵建議用 id 標簽 -->
    <result property="username" column="user_name"/>
    <result property="email" column="email_addr"/>
    <result property="createTime" column="gmt_create"/>
</resultMap>
<select id="getUserById" resultMap="UserResultMap">
    SELECT user_id, user_name, email_addr, gmt_create 
    FROM user_info 
    WHERE user_id = #{id}
</select>

?? id 標簽用于主鍵,有助于性能優(yōu)化(緩存、嵌套查詢?nèi)ブ兀?/p>

四、處理對象嵌套 —— association

當 User 包含一個 Profile 對象:

public class User {
    private Long id;
    private String username;
    private Profile profile; // 嵌套對象
}
public class Profile {
    private String avatar;
    private String bio;
}

XML 映射:

<resultMap id="UserWithProfileResultMap" type="User">
    <id property="id" column="user_id"/>
    <result property="username" column="username"/>
    <!-- 嵌套對象映射 -->
    <association property="profile" javaType="Profile">
        <result property="avatar" column="avatar_url"/>
        <result property="bio" column="user_bio"/>
    </association>
</resultMap>
<select id="getUserWithProfile" resultMap="UserWithProfileResultMap">
    SELECT u.id as user_id, u.username,
           p.avatar as avatar_url, p.bio as user_bio
    FROM user u
    LEFT JOIN profile p ON u.id = p.user_id
    WHERE u.id = #{id}
</select>

五、處理集合嵌套 —— collection

當 User 包含多個 Role:

public class User {
    private Long id;
    private String username;
    private List<Role> roles; // 集合
}
public class Role {
    private Long id;
    private String roleName;
}

XML 映射:

<resultMap id="UserWithRolesResultMap" type="User">
    <id property="id" column="user_id"/>
    <result property="username" column="username"/>
    <!-- 集合映射 -->
    <collection property="roles" ofType="Role">
        <id property="id" column="role_id"/>
        <result property="roleName" column="role_name"/>
    </collection>
</resultMap>
<select id="getUserWithRoles" resultMap="UserWithRolesResultMap">
    SELECT u.id as user_id, u.username,
           r.id as role_id, r.name as role_name
    FROM user u
    LEFT JOIN user_role ur ON u.id = ur.user_id
    LEFT JOIN role r ON ur.role_id = r.id
    WHERE u.id = #{id}
</select>

?? 注意:使用 ofType 指定集合元素類型,而不是 javaType

六、避免 N+1 查詢問題

上面的寫法雖然能正確封裝,但可能引發(fā) N+1 查詢。推薦使用 JOIN 查詢 + 分組封裝分步查詢(懶加載)

方案一:分步查詢(推薦用于懶加載)

<resultMap id="UserLazyLoadResultMap" type="User">
    <id property="id" column="id"/>
    <result property="username" column="username"/>
    <collection property="roles" 
                select="selectRolesByUserId" 
                column="id" 
                fetchType="lazy"/>
</resultMap>
<select id="selectUserById" resultMap="UserLazyLoadResultMap">
    SELECT id, username FROM user WHERE id = #{id}
</select>
<select id="selectRolesByUserId" resultType="Role">
    SELECT id, name as roleName FROM role 
    WHERE id IN (SELECT role_id FROM user_role WHERE user_id = #{userId})
</select>

在配置中開啟懶加載:

mybatis:
  configuration:
    lazy-loading-enabled: true
    aggressive-lazy-loading: false

七、使用注解簡化映射(可選)

對于簡單場景,也可使用注解:

@Results(id = "UserResult", value = {
    @Result(property = "id", column = "user_id"),
    @Result(property = "username", column = "user_name"),
    @Result(property = "profile", column = "user_id",
            one = @One(select = "selectProfileByUserId"))
})
@Select("SELECT user_id, user_name FROM user WHERE id = #{id}")
User getUserById(Long id);

八、實戰(zhàn)技巧 & 避坑指南

? 技巧 1:統(tǒng)一別名規(guī)范

在 SQL 中使用 AS 給字段起別名,避免列名沖突:

SELECT u.id AS user_id, r.id AS role_id, ...

? 技巧 2:復(fù)用 ResultMap

使用 <extend> 繼承已有的 ResultMap:

<resultMap id="BaseUserMap" type="User">
    <id property="id" column="id"/>
    <result property="username" column="username"/>
</resultMap>
<resultMap id="UserWithProfileMap" extends="BaseUserMap">
    <association property="profile" ... />
</resultMap>

? 技巧 3:自動映射策略

<resultMap autoMapping="true" ...>

開啟后,未明確指定的匹配字段也會自動映射(需配合駝峰轉(zhuǎn)換)。

? 避坑 1:不要混用 resultType 和 resultMap

在一個 select 標簽內(nèi)只能使用其一。

? 避坑 2:集合屬性未初始化

確保 Java 實體中的 List 屬性已初始化:

private List<Role> roles = new ArrayList<>(); // 避免 null

九、終極解決方案:MyBatis-Plus(可選進階)

如果你覺得原生 MyBatis 配置繁瑣,可以考慮 MyBatis-Plus

  • 無需 XML,注解/條件構(gòu)造器即可完成復(fù)雜查詢
  • 內(nèi)置 ResultMap 自動構(gòu)建
  • 支持連表查詢插件(如 @TableField(select = false) + QueryWrapper 聯(lián)查)
  • 分頁、樂觀鎖、代碼生成器一應(yīng)俱全

示例:

// MP 自動處理字段映射 + 駝峰
List<User> users = userMapper.selectList(
    Wrappers.<User>lambdaQuery()
        .eq(User::getUsername, "admin")
);

總結(jié)

問題類型解決方案
字段名不匹配開啟駝峰 / 使用 <result>
對象嵌套<association>
集合嵌套<collection>
性能優(yōu)化分步查詢 + 懶加載
復(fù)雜聯(lián)查ResultMap + SQL 別名
快速開發(fā)MyBatis-Plus

掌握以上方法,你將能從容應(yīng)對 MyBatis 中 99% 的數(shù)據(jù)封裝問題!記得收藏本文,下次遇到映射失敗時,按圖索驥,輕松解決!

到此這篇關(guān)于MyBatis 數(shù)據(jù)封裝全攻略(告別空值與映射混亂問題)的文章就介紹到這了,更多相關(guān)MyBatis 數(shù)據(jù)封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java Mail郵件接收工具類

    java Mail郵件接收工具類

    這篇文章主要介紹了java Mail郵件接收工具類,本文直接給出類實現(xiàn)代碼和使用示例,需要的朋友可以參考下
    2015-02-02
  • 一文帶你了解Java排序算法

    一文帶你了解Java排序算法

    這篇文章主要為大家詳細介紹了Java中常見的三個排序算法:選擇排序,冒泡排序和插入排序,文中的示例代碼講解詳細,感興趣的可以了解一下
    2022-08-08
  • springboot全局異常處理代碼實例

    springboot全局異常處理代碼實例

    這篇文章主要介紹了springboot全局異常處理代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • SpringBoot事務(wù)鉤子函數(shù)的使用方式

    SpringBoot事務(wù)鉤子函數(shù)的使用方式

    本文介紹了SpringBoot中事務(wù)鉤子函數(shù)的使用方式,包括常見場景、使用方式等,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • 淺析Java中的 new 關(guān)鍵字

    淺析Java中的 new 關(guān)鍵字

    java中的new關(guān)鍵字是實例化對象,接下來本文通過一個案例給大家講解Java中的 new 關(guān)鍵字,感興趣的朋友可以參考下
    2016-08-08
  • Java Swing實現(xiàn)掃雷小游戲

    Java Swing實現(xiàn)掃雷小游戲

    這篇文章主要為大家詳細介紹了Java Swing實現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • hadoop?全面解讀自定義分區(qū)

    hadoop?全面解讀自定義分區(qū)

    Hadoop是一個由Apache基金會所開發(fā)的分布式系統(tǒng)基礎(chǔ)架構(gòu)。用戶可以在不了解分布式底層細節(jié)的情況下,開發(fā)分布式程序。充分利用集群的威力進行高速運算和存儲
    2022-02-02
  • 在項目中集成jetty server步驟解析

    在項目中集成jetty server步驟解析

    這篇文章主要介紹了在項目中集成jetty server步驟解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Java中使用數(shù)組實現(xiàn)棧數(shù)據(jù)結(jié)構(gòu)實例

    Java中使用數(shù)組實現(xiàn)棧數(shù)據(jù)結(jié)構(gòu)實例

    這篇文章主要介紹了Java中使用數(shù)組實現(xiàn)棧數(shù)據(jù)結(jié)構(gòu)實例,本文先是講解了實現(xiàn)棧至少應(yīng)該包括以下幾個方法等知識,然后給出代碼實例,需要的朋友可以參考下
    2015-01-01
  • 詳解Spring中的AOP及AspectJ五大通知注解

    詳解Spring中的AOP及AspectJ五大通知注解

    這篇文章主要介紹了詳解Spring中的AOP及AspectJ五大通知注解,AOP面向切面編程是一種新的方法論,是對傳統(tǒng)OOP面向?qū)ο缶幊痰难a充,AOP?的主要編程對象是切面(aspect),切面模塊化橫切關(guān)注點,需要的朋友可以參考下
    2023-08-08

最新評論