一、背景 今天一个线上问题报错如下: org。apache。ibatis。exceptions。TooManyResultsException: Expectedoneresult(ornull)tobereturnedbyselectOne(),butfound:2 通过报错信息可以知道这个是一个数据查询结果集不符的问题,程序中预期是只有一条数据的,但是查出来的结果有多个。 二、问题排查 先看数据:提取出来SQL语句执行发现真的是有2条符合记录 那就是SQL语句的编写有问题,定位SQL语句产生的那一行代码 发现使用了MyBatisPlus的LambdaQuery()查询中的one()方法 PS:这里贴一下出错的代码行 BHOrderCargoSizeEntitysplitCargoSize bhOrderCargoSizeService。lambdaQuery()。eq(BHOrderCargoSizeEntity::getSplitId,x。getId())。one(); 三、问题深究3。1、selectOne()第一印象 可能对于多数人one()方法给人的第一印象是:取查询结果的其中一个然后返回3。2、真正的selectOne() 既然都已经产生的错误那selectOne()的实际操作肯定不是和上面的想的一样的。我们点进去MP的源码可以看到如下: 先点击去One()方法可以看到如下:这里是MyBatisPlus源码获取单个return单个defaultTone(){returngetBaseMapper()。selectOne(getWrapper());} Java 这里可以看到是调用了selectOne()方法,同样我们在使用条件构造器进行查询时:日常项目中构造器查询代码示例OverridepublicUserEntityqueryByMobile(Stringmobile){returnbaseMapper。selectOne(newQueryWrapperUserEntity()。eq(mobile,mobile));} Java 其中的selectOne()操作也是单条数据查询的。 于是我们找到如下部分代码:这里是MyBatisPlus源码OverridepublicTgetOne(WrapperTqueryWrapper,booleanthrowEx){if(throwEx){returnbaseMapper。selectOne(queryWrapper);}returnSqlHelper。getObject(baseMapper。selectList(queryWrapper));} 我们可以发现: 。有异常抛给上层处理 。正常情况下getOne()的操作是selectList()实现的 当有多条数据时就有了如下的情况:这里是MyBatisPlus源码p从list中取第一条数据返回对应List中泛型的单个结果paramlistparamEreturnpublicstaticEEgetObject(ListElist){if(CollectionUtils。isNotEmpty(list)){intsizelist。size();if(size1){logger。warn(String。format(Warn:executeMethodTherearesresults。,size));}returnlist。get(0);}} 通过上述表明: 。当只有一条数据返回时程序才能正常执行 。当数据返回多条时就会给出异常提示了 四、问题解决 直接使用MyBatisPlus的last方法在sql末尾追加语句limit1,代码如下: BHOrderCargoSizeEntitysplitCargoSize bhOrderCargoSizeService。lambdaQuery()。eq(BHOrderCargoSizeEntity::getSplitId,x。getId())。last(limit1)。one(); 网上有一些重写selectOne方法的,基本通过重写或切面编程。有兴趣可以了解下(不建议新手这样操作!) PS:关于MyBatisPlus的语法知识点也可以参考我之前的文章: 初见MyBatisPlus 五、后记 遇到问题只知道怎么解决是不够的,能追其本质才是乐趣所在。