随州市网站建设_网站建设公司_在线商城_seo优化
2026/1/9 6:39:06 网站建设 项目流程

登录接口异常:selectOne() 返回多条结果(Expected one result but found:2)

你现在遇到的异常是Expected one result (or null) to be returned by selectOne(), but found: 2,核心原因是:你用selectOne()方法查询用户(admin),但数据库中符合条件的sys_user记录有2条,而selectOne()要求只能返回0条或1条结果

结合你之前的登录日志(SQL:SELECT user_name, status FROM sys_user WHERE del_flag = '0' AND (user_name = 'admin')),下面一步步讲清楚原因、排查方法和解决方案。

一、先理解异常本质

selectOne()是 MyBatis 提供的方法,设计初衷是:

  • 期望查询结果最多1条(0条返回null,1条返回实体);
  • 如果返回多条(比如2条),直接抛出上述异常。

你的场景中,数据库里sys_user表存在2条user_name='admin'del_flag='0'的记录,触发了这个异常。

二、第一步:排查数据库数据(快速定位)

先执行SQL确认重复数据,这是最直接的方式:

-- 执行以下SQL,查看有多少条admin用户记录SELECTid,user_name,status,del_flagFROMsys_userWHEREdel_flag='0'ANDuser_name='admin';

执行后会看到结果行数为2,甚至更多——这就是异常的根源。

为什么会出现重复的admin用户?

常见原因:

  1. 手动插入时重复创建了admin账号;
  2. 代码中新增用户逻辑有BUG,重复插入;
  3. user_name字段未设置唯一索引,导致重复插入。

三、第二步:解决方案(分「紧急修复」和「长期预防」)

1. 紧急修复:清理重复数据(立即解决异常)

先删除/禁用重复的admin记录,保留一条有效记录:

-- 1. 查看重复记录的ID(假设ID为1和2)SELECTid,user_nameFROMsys_userWHEREuser_name='admin'ANDdel_flag='0';-- 2. 禁用重复记录(推荐,不直接删除,保留数据)UPDATEsys_userSETdel_flag='1'WHEREid=2;-- 禁用ID=2的重复记录-- 或直接删除(谨慎!备份后操作)DELETEFROMsys_userWHEREid=2;

执行后重新测试登录接口,异常会立即消失。

2. 代码层面优化(避免后续触发)

即使清理了重复数据,也建议优化代码,增加容错性:

(1)替换selectOne()selectList(),手动处理结果
// 原错误代码(用selectOne,易触发异常)SysUseruser=sysUserMapper.selectOne(newQueryWrapper<SysUser>().eq("user_name","admin").eq("del_flag","0"));// 优化后代码(用selectList,手动处理多条结果)List<SysUser>userList=sysUserMapper.selectList(newQueryWrapper<SysUser>().eq("user_name","admin").eq("del_flag","0"));SysUseruser=null;if(CollectionUtils.isEmpty(userList)){// 无用户,返回账号不存在log.warn("用户admin不存在");}elseif(userList.size()>1){// 多条用户,记录日志并抛出明确异常(或取第一条)log.error("发现多条admin用户记录,数量:{}",userList.size());// 可选:取第一条有效记录,或抛出业务异常user=userList.get(0);// 或抛出异常:throw new BusinessException("账号异常,请联系管理员");}else{// 正常情况,取唯一记录user=userList.get(0);}
(2)给user_name加唯一索引(从根上防止重复)

在数据库中给sys_user.user_name添加唯一索引,避免重复插入:

-- 给user_name添加唯一索引(包含del_flag,避免禁用后仍无法新增)ALTERTABLEsys_userADDUNIQUEINDEXidx_user_name_del_flag(user_name,del_flag);

⚠️ 说明:联合索引(user_name, del_flag)意味着「同一用户名+同一删除状态」只能有一条记录,既防止重复有效用户,又允许禁用后重新创建同名用户。

3. 补充:MyBatis-Plus 场景的优化

如果你用的是 MyBatis-Plus,也可以用getOne()方法并指定容错策略:

// MyBatis-Plus的getOne方法,支持指定当多条结果时取第一条SysUseruser=sysUserService.getOne(newQueryWrapper<SysUser>().eq("user_name","admin").eq("del_flag","0"),false// false表示多条结果时取第一条,true表示抛出异常(默认));

四、总结(核心要点)

  1. 异常根因selectOne()查询admin用户返回2条记录,违反其“最多1条”的设计规则;
  2. 紧急修复:清理数据库中重复的admin记录(禁用/删除);
  3. 长期预防
    • 代码层面:用selectList()替代selectOne(),手动处理多条结果;
    • 数据库层面:给user_name加唯一索引,防止重复插入;
  4. 关键提醒:用户名字段是核心唯一标识,必须通过唯一索引保障唯一性,避免类似问题复发。

如果清理数据后仍有异常,可贴出sys_user表的admin记录查询结果,我帮你进一步分析!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询