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

MyBatis多表聯(lián)查返回List僅一條數(shù)據(jù)?主鍵沖突BUG排查與解決方案

 更新時間:2026年04月09日 16:54:45   作者:Tech_Jia_Hui  
在項目開發(fā)中,通過MyBatis實現(xiàn)“管理員-角色-權(quán)限”多表關(guān)聯(lián)查詢時,遇到SQL執(zhí)行返回多條結(jié)果但MyBatis映射后List集合只顯示一條數(shù)據(jù)的BUG,最終定位到是主鍵字段命名沖突導(dǎo)致,通過為SQL中同名字段起別名并修正ResultMap配置,成功修復(fù)了BUG

一、問題背景

在項目開發(fā)中,多表聯(lián)查是高頻需求。近期在基于MyBatis實現(xiàn)"管理員-角色-權(quán)限"多表關(guān)聯(lián)查詢時,遇到了一個詭異的BUG:數(shù)據(jù)庫執(zhí)行SQL能返回多條正確結(jié)果,但項目中通過MyBatis映射后,List集合始終只顯示一條數(shù)據(jù)。

經(jīng)過反復(fù)排查,最終定位到是主鍵字段命名沖突導(dǎo)致MyBatis數(shù)據(jù)映射異常,現(xiàn)將完整排查過程與解決方案分享如下。

二、問題復(fù)現(xiàn)

2.1 業(yè)務(wù)場景

需通過管理員ID查詢該管理員的基本信息、關(guān)聯(lián)的角色列表,以及每個角色對應(yīng)的權(quán)限列表,涉及admin(管理員表)、role(角色表)、permission(權(quán)限表)三張核心表,通過中間表admin_rolerole_permission實現(xiàn)關(guān)聯(lián)。

2.2 核心代碼實現(xiàn)

1. Mapper.xml查詢SQL

SELECT
    a.id,
    a.username,
    r.id,
    r.role_name,
    r.role_desc,
    p.id,
    p.permission_name,
    p.url
FROM
    `admin` a
    LEFT JOIN admin_role ON a.id = admin_role.aid
    LEFT JOIN `role` r ON admin_role.rid = r.id
    LEFT JOIN role_permission ON r.id = role_permission.rid
    LEFT JOIN permission p ON role_permission.pid = p.id
WHERE
    a.id = #{aid}

直接在數(shù)據(jù)庫執(zhí)行該SQL,返回2條結(jié)果(對應(yīng)2個權(quán)限),數(shù)據(jù)正常。

2. ResultMap配置

<resultMap id="adminMapper" type="com.lion.online.pojo.Admin">
    <id property="id" column="id"></id>
    <result property="username" column="username"></result>
    <!-- 角色列表關(guān)聯(lián) -->
    <collection property="roles" column="id" ofType="com.lion.online.pojo.Role">
        <id property="id" column="id"></id>
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
        <!-- 權(quán)限列表關(guān)聯(lián) -->
        <collection property="permissions" column="id" ofType="com.lion.online.pojo.Permission">
            <id property="id" column="id"/>
            <result property="permissionName" column="permission_name"></result>
            <result property="url" column="url"></result>
        </collection>
    </collection>
</resultMap>

3. 異常結(jié)果

項目運行后,控制臺打印SQL執(zhí)行結(jié)果為2條,但頁面僅顯示1條權(quán)限數(shù)據(jù),List集合長度異常為1。

三、BUG根源分析

3.1 核心問題:字段名沖突

MyBatis的ResultMap中,id標(biāo)簽用于標(biāo)識實體類的主鍵字段,其column屬性對應(yīng)查詢結(jié)果集中的列名(而非數(shù)據(jù)庫表字段名)。本案例中:

  • 管理員表、角色表、權(quán)限表的主鍵均命名為id
  • 查詢SQL未對多表中的id字段起別名,導(dǎo)致結(jié)果集中出現(xiàn)多個同名id
  • MyBatis在映射數(shù)據(jù)時,無法區(qū)分主表(admin)、關(guān)聯(lián)表(role、permission)的id字段,誤將所有id列值當(dāng)作主表主鍵處理,最終只保留了一條去重后的數(shù)據(jù)

3.2 關(guān)鍵原理

ResultMapid標(biāo)簽具有"數(shù)據(jù)唯一標(biāo)識"的作用,MyBatis會根據(jù)id字段的值判斷是否為同一實體。

當(dāng)多表id字段同名且未區(qū)分時,MyBatis會認(rèn)為所有關(guān)聯(lián)數(shù)據(jù)屬于同一個實體,從而覆蓋重復(fù)數(shù)據(jù),導(dǎo)致最終返回結(jié)果條數(shù)少于實際查詢結(jié)果。

四、解決方案

核心思路:通過SQL別名區(qū)分多表中的同名id字段,在ResultMap中明確映射對應(yīng)關(guān)系。

4.1 優(yōu)化查詢SQL(添加字段別名)

對角色表id起別名rid,權(quán)限表id起別名pid,避免列名沖突:

SELECT
    a.id,
    a.username,
    r.id AS rid,  -- 角色I(xiàn)D別名
    r.role_name,
    r.role_desc,
    p.id AS pid,  -- 權(quán)限ID別名
    p.permission_name,
    p.url
FROM
    `admin` a
    LEFT JOIN admin_role ON a.id = admin_role.aid
    LEFT JOIN `role` r ON admin_role.rid = r.id
    LEFT JOIN role_permission ON r.id = role_permission.rid
    LEFT JOIN permission p ON role_permission.pid = p.id
WHERE
    a.id = #{aid}

4.2 修正ResultMap配置(映射別名列)

更新ResultMapcollection標(biāo)簽的column屬性,指向SQL中定義的別名:

<resultMap id="adminMapper" type="com.lion.online.pojo.Admin">
    <!-- 管理員主表映射 -->
    <id property="id" column="id"></id>
    <result property="username" column="username"></result>
    <!-- 角色列表關(guān)聯(lián):column指向角色I(xiàn)D別名rid -->
    <collection property="roles" column="rid" ofType="com.lion.online.pojo.Role">
        <id property="id" column="rid"></id>  <!-- 角色主鍵映射別名列 -->
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
        <!-- 權(quán)限列表關(guān)聯(lián):column指向權(quán)限ID別名pid -->
        <collection property="permissions" column="pid" ofType="com.lion.online.pojo.Permission">
            <id property="id" column="pid"/>  <!-- 權(quán)限主鍵映射別名列 -->
            <result property="permissionName" column="permission_name"></result>
            <result property="url" column="url"></result>
        </collection>
    </collection>
</resultMap>

4.3 優(yōu)化說明

  1. SQL別名命名規(guī)范:建議采用"表名首字母+id"的格式(如rid=role_id、pid=permission_id),提高可讀性
  2. collection標(biāo)簽的column屬性:需與SQL別名完全一致,確保MyBatis能正確匹配關(guān)聯(lián)數(shù)據(jù)
  3. 主鍵映射優(yōu)先級:id標(biāo)簽的映射優(yōu)先級高于result標(biāo)簽,必須優(yōu)先確保主鍵字段映射正確

五、驗證結(jié)果

優(yōu)化后重新運行項目,頁面成功展示所有關(guān)聯(lián)數(shù)據(jù):

List集合長度與數(shù)據(jù)庫查詢結(jié)果一致,BUG修復(fù)完成。

六、避坑總結(jié)

  1. 多表聯(lián)查必注意:只要涉及多張表,必須對同名字段起別名,尤其是主鍵id
  2. ResultMap映射原則:column屬性對應(yīng)"查詢結(jié)果集的列名",而非數(shù)據(jù)庫表字段名,別名變更需同步更新

七、總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

巴青县| 金门县| 公主岭市| 华蓥市| 内黄县| 贞丰县| 民丰县| 信宜市| 桐城市| 孟州市| 略阳县| 肥西县| 临沭县| 嘉祥县| 井冈山市| 武鸣县| 鹿泉市| 抚宁县| 珲春市| 新密市| 天门市| 阿坝县| 辰溪县| 酒泉市| 息烽县| 雅安市| 托里县| 南川市| 和静县| 汕头市| 巴彦淖尔市| 华安县| 竹山县| 泰兴市| 灵寿县| 集贤县| 乌恰县| 突泉县| 长顺县| 集安市| 巫溪县|