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

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

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

一、問題背景

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

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

二、問題復現(xiàn)

2.1 業(yè)務場景

需通過管理員ID查詢該管理員的基本信息、關聯(lián)的角色列表,以及每個角色對應的權限列表,涉及admin(管理員表)、role(角色表)、permission(權限表)三張核心表,通過中間表admin_rolerole_permission實現(xià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條結果(對應2個權限),數(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>
    <!-- 角色列表關聯(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>
        <!-- 權限列表關聯(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. 異常結果

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

三、BUG根源分析

3.1 核心問題:字段名沖突

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

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

3.2 關鍵原理

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

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

四、解決方案

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

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

對角色表id起別名rid,權限表id起別名pid,避免列名沖突:

SELECT
    a.id,
    a.username,
    r.id AS rid,  -- 角色ID別名
    r.role_name,
    r.role_desc,
    p.id AS pid,  -- 權限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標簽的column屬性,指向SQL中定義的別名:

<resultMap id="adminMapper" type="com.lion.online.pojo.Admin">
    <!-- 管理員主表映射 -->
    <id property="id" column="id"></id>
    <result property="username" column="username"></result>
    <!-- 角色列表關聯(lián):column指向角色ID別名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>
        <!-- 權限列表關聯(lián):column指向權限ID別名pid -->
        <collection property="permissions" column="pid" ofType="com.lion.online.pojo.Permission">
            <id property="id" column="pid"/>  <!-- 權限主鍵映射別名列 -->
            <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標簽的column屬性:需與SQL別名完全一致,確保MyBatis能正確匹配關聯(lián)數(shù)據(jù)
  3. 主鍵映射優(yōu)先級:id標簽的映射優(yōu)先級高于result標簽,必須優(yōu)先確保主鍵字段映射正確

五、驗證結果

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

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

六、避坑總結

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

七、總結

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

相關文章

最新評論

奉新县| 交城县| 鸡泽县| 工布江达县| 云和县| 宝兴县| 漾濞| 措美县| 得荣县| 安顺市| 登封市| 青阳县| 宕昌县| 开远市| 文水县| 营山县| 贵德县| 格尔木市| 张家港市| 锦屏县| 雅江县| 阳江市| 赞皇县| 安岳县| 格尔木市| 海盐县| 长丰县| 明光市| 仙居县| 仁寿县| 淮阳县| 建德市| 韶山市| 德清县| 濉溪县| 大同县| 手游| 同仁县| 门头沟区| 班戈县| 辰溪县|