当前位置: 首页 > news >正文

MyBatis多表联查返回List仅一条数据?主键冲突BUG排查与解决

    • 一、问题背景
    • 二、问题复现
      • 2.1 业务场景
      • 2.2 核心代码实现
        • 1. Mapper.xml查询SQL
        • 2. ResultMap配置
        • 3. 异常结果
    • 三、BUG根源分析
      • 3.1 核心问题:字段名冲突
      • 3.2 关键原理
    • 四、解决方案
      • 4.1 优化查询SQL(添加字段别名)
      • 4.2 修正ResultMap配置(映射别名列)
      • 4.3 优化说明
    • 五、验证结果
    • 六、避坑总结

一、问题背景

在项目开发中,多表联查是高频需求。近期在基于MyBatis实现"管理员-角色-权限"多表关联查询时,遇到了一个诡异的BUG:数据库执行SQL能返回多条正确结果,但项目中通过MyBatis映射后,List集合始终只显示一条数据。经过反复排查,最终定位到是主键字段命名冲突导致MyBatis数据映射异常,现将完整排查过程与解决方案分享如下。

二、问题复现

2.1 业务场景

需通过管理员ID查询该管理员的基本信息、关联的角色列表,以及每个角色对应的权限列表,涉及admin(管理员表)、role(角色表)、permission(权限表)三张核心表,通过中间表admin_rolerole_permission实现关联。

2.2 核心代码实现

1. Mapper.xml查询SQL
SELECTa.id,a.username,r.id,r.role_name,r.role_desc,p.id,p.permission_name,p.url
FROM`admin` aLEFT JOIN admin_role ON a.id = admin_role.aidLEFT JOIN `role` r ON admin_role.rid = r.idLEFT JOIN role_permission ON r.id = role_permission.ridLEFT JOIN permission p ON role_permission.pid = p.id
WHEREa.id = #{aid}

直接在数据库执行该SQL,返回2条结果(对应2个权限),数据正常。

2. ResultMap配置
<resultMap id="adminMapper" type="com.lion.online.pojo.Admin"><id property="id" column="id"></id><result property="username" column="username"></result><!-- 角色列表关联 --><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><!-- 权限列表关联 --><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执行结果为2条,但页面仅显示1条权限数据,List集合长度异常为1。

三、BUG根源分析

3.1 核心问题:字段名冲突

MyBatis的ResultMap中,id标签用于标识实体类的主键字段,其column属性对应查询结果集中的列名(而非数据库表字段名)。本案例中:

  • 管理员表、角色表、权限表的主键均命名为id
  • 查询SQL未对多表中的id字段起别名,导致结果集中出现多个同名id
  • MyBatis在映射数据时,无法区分主表(admin)、关联表(role、permission)的id字段,误将所有id列值当作主表主键处理,最终只保留了一条去重后的数据

3.2 关键原理

ResultMapid标签具有"数据唯一标识"的作用,MyBatis会根据id字段的值判断是否为同一实体。当多表id字段同名且未区分时,MyBatis会认为所有关联数据属于同一个实体,从而覆盖重复数据,导致最终返回结果条数少于实际查询结果。

四、解决方案

核心思路:通过SQL别名区分多表中的同名id字段,在ResultMap中明确映射对应关系。

4.1 优化查询SQL(添加字段别名)

对角色表id起别名rid,权限表id起别名pid,避免列名冲突:

SELECTa.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` aLEFT JOIN admin_role ON a.id = admin_role.aidLEFT JOIN `role` r ON admin_role.rid = r.idLEFT JOIN role_permission ON r.id = role_permission.ridLEFT JOIN permission p ON role_permission.pid = p.id
WHEREa.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><!-- 角色列表关联: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><!-- 权限列表关联: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 优化说明

  1. SQL别名命名规范:建议采用"表名首字母+id"的格式(如rid=role_id、pid=permission_id),提高可读性
  2. collection标签的column属性:需与SQL别名完全一致,确保MyBatis能正确匹配关联数据
  3. 主键映射优先级:id标签的映射优先级高于result标签,必须优先确保主键字段映射正确

五、验证结果

优化后重新运行项目,页面成功展示所有关联数据:

List集合长度与数据库查询结果一致,BUG修复完成。

六、避坑总结

  1. 多表联查必注意:只要涉及多张表,必须对同名字段起别名,尤其是主键id
  2. ResultMap映射原则:column属性对应"查询结果集的列名",而非数据库表字段名,别名变更需同步更新
http://www.dtcms.com/a/601427.html

相关文章:

  • c 做网站方便吗手机企业wap网站
  • el-table有固定列时样式bug
  • Vue项目中 安装及使用Sass(scss)
  • 珠海本地网站设计公司什么网站可以发布信息
  • UEFI+GPT平台一键安装Windows方法
  • GPT‑5 全面解析与开发者接入指南
  • 站优云seo优化页面模板这样选
  • dism++功能实操备份与还原
  • 动态型网站建设哪里便宜app开发需要用到哪些工具
  • 网站建设的什么是网站建设的第一阶段佛山市房产信息网
  • React 18
  • CVPR 2025|电子科大提出渐进聚焦Transformer:显著降低超分辨率计算开销
  • CTFHub Web进阶-Linux:动态装载
  • Nginx域名与SSL证书配置完整流程
  • 美食网站要怎么做自己做相册的网站
  • 全国 网站备案 数量电子设计工程官网
  • 一、UDP以太网帧格式
  • 网络协议设计原则简介和资料推荐
  • 有哪些程序网站品牌和商标的区别
  • C语言编译器选择指南 | 初学者实用教程
  • 小智机器人MCP
  • 对于给不良网站发律师函如何做收银系统哪个软件好
  • 网站管理工作总结安阳县事业单位招聘2021
  • RK-Android11-修改系统的鼠标光标
  • vs2022 IDE扩展无法卸载/VSI 插件卸载及实例清理
  • 华为OD机试 双机位A卷 - 智能驾驶 (JAVA Python C++ JS GO)
  • 广州网站制作实力乐云seo怎么提高网站的流量
  • 开源工具 yt-dlp 超简易上手版
  • 郑州网站优化外包顾问上海网站建设 分类广告
  • SSM基于WEB的教学质量评价系统的设计与实现p9ak6(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。