最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

這些問題本質上都是 數(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)點:簡潔、易用
? 缺點:無法處理駝峰命名、多表關聯(lián)、嵌套對象等復雜場景

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

二、開啟駝峰命名轉換(推薦基礎配置)

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_nameuserNamecreate_timecreateTime 自動映射。

三、resultMap —— 精準控制映射關系

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

基礎字段映射

<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)化(緩存、嵌套查詢去重)

四、處理對象嵌套 —— 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:復用 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" ...>

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

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

在一個 select 標簽內只能使用其一。

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

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

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

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

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

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

示例:

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

總結

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

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

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

相關文章

  • SpringBoot異步方法捕捉異常詳解

    SpringBoot異步方法捕捉異常詳解

    這篇文章主要為大家詳細介紹了SpringBoot異步方法捕捉異常,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • Java使用EasyExcel實現(xiàn)對excel文件的讀寫方式

    Java使用EasyExcel實現(xiàn)對excel文件的讀寫方式

    這篇文章主要介紹了Java使用EasyExcel實現(xiàn)對excel文件的讀寫方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • MyBatis #{}和${} |與數(shù)據(jù)庫連接池使用詳解

    MyBatis #{}和${} |與數(shù)據(jù)庫連接池使用詳解

    本文將為大家說說關于 #{} 和 ${},這個是 MyBatis 在面試中最常問的面試題,以及數(shù)據(jù)庫連接池相關的知識,感興趣的朋友跟隨小編一起看看吧
    2024-01-01
  • Java中int[]與ArrayList<>數(shù)組轉換方法詳解

    Java中int[]與ArrayList<>數(shù)組轉換方法詳解

    這篇文章主要介紹了在Java中將int[]和ArrayList進行雙向轉換的方法,包括手動遍歷和使用Java8?Stream?API兩種方式,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-02-02
  • Java設計模式之Builder建造者模式

    Java設計模式之Builder建造者模式

    這篇文章主要為大家詳細介紹了Java設計模式之Builder建造者模式的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Java借助Spire.PDF?for?Java高效實現(xiàn)PDF自動排版

    Java借助Spire.PDF?for?Java高效實現(xiàn)PDF自動排版

    在?Java?開發(fā)中,處理?PDF?文檔的生成與編輯是常見的需求,本文將深入探討如何利用?Java?高效準確地設置?PDF?中的文字對齊方式,感興趣的小伙伴可以了解下
    2026-01-01
  • 使用自定義Json注解實現(xiàn)輸出日志字段脫敏

    使用自定義Json注解實現(xiàn)輸出日志字段脫敏

    這篇文章主要介紹了使用自定義Json注解實現(xiàn)輸出日志字段脫敏,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • IDEA 格式化SQL代碼技巧分享

    IDEA 格式化SQL代碼技巧分享

    這篇文章主要介紹了IDEA 格式化SQL代碼技巧分享,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Spring mvc Json處理實現(xiàn)流程代碼實例

    Spring mvc Json處理實現(xiàn)流程代碼實例

    這篇文章主要介紹了Spring mvc Json處理實現(xiàn)流程代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • 談談Java中自定義注解及使用場景

    談談Java中自定義注解及使用場景

    這篇文章主要介紹了談談Java中自定義注解及使用場景,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09

最新評論

杂多县| 元谋县| 永和县| 乐安县| 河北区| 芒康县| 崇礼县| 金阳县| 宁都县| 宁都县| 福州市| 沙河市| 南溪县| 静乐县| 牡丹江市| 县级市| 玉屏| 贵州省| 祁东县| 陵水| 罗田县| 溧水县| 平遥县| 平遥县| 特克斯县| 名山县| 台山市| 曲松县| 泸溪县| 孟州市| 都昌县| 凌源市| 辽源市| 丹棱县| 靖江市| 霸州市| 祥云县| 嘉定区| 济宁市| 贺兰县| 舒城县|