解决java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条问题

 更新时间:2026年04月09日 16:41:38   作者:svygh123  
文章解释了一个系统问题,尽管SQL写了limit 1且MyBatis的debug日志显示total为1,但仍返回了1805条数据,原因是selectOne方法只查询一条记录,若有多条则报错,而非智能筛选,文章还分析了MyBatisPlus和MyBatis中selectOne方法的不同实现

今天遇到一个问题

系统线上问题

  • 经常出现这样的问题,刚重启系统时不报错了,可是运行一段时间又会出现。
  • sql已经写了limit 1,mybatis的debug日志也返回total为1,可是却报错返回了1805条数据

 

 

乍一看,感觉太不可思议了 

其实还是被默认的东西给坑到了,也不能说是坑,就是不理解里面的原理,拿来就用,以为是这个功能,其实还有隐藏的内幕在里面。

这个里面的东西就是selectOne方法,这个方法,我们以为的查询方式是这样的:

select code,username,sex,age,birth from t_user where code=#[code] limit 1

但是它里面并没有那么智能,就像它的名字selectOne一样,你想查询一条记录,那么我就帮你查一条记录,如果有多条记录,那么我报错也是合情合理的吧,毕竟你只查一条记录,也没有说要查哪一条是吧。

实际上

MyBatis Plus(com.baomidou.mybatisplus.core.mapper.BaseMapper.selectOne)是这样的:

/**
     * 根据 entity 条件,查询一条记录,现在会根据{@code throwEx}参数判断是否抛出异常,如果为false就直接返回一条数据
     * <p>查询一条记录,例如 qw.last("limit 1") 限制取一条记录, 注意:多条数据会报异常</p>
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     * @param throwEx      boolean 参数,为true如果存在多个结果直接抛出异常
     */
    default T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper, boolean throwEx) {
        List<T> list = this.selectList(queryWrapper);
        // 抄自 DefaultSqlSession#selectOne
        int size = list.size();
        if (size == 1) {
            return list.get(0);
        } else if (size > 1) {
            if (throwEx) {
                throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
            }
            return list.get(0);
        }
        return null;
    }

而MyBatis(org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne)是这样的:

@Override
  public <T> T selectOne(String statement, Object parameter) {
    // Popular vote was to return null on 0 results and throw exception on too many.
    List<T> list = this.selectList(statement, parameter);
    if (list.size() == 1) {
      return list.get(0);
    }
    if (list.size() > 1) {
      throw new TooManyResultsException(
          "Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
    } else {
      return null;
    }
  }

是吧,拿来的东西固然好,但是也要花点时间学习里面的精髓。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot拦截器excludePathPatterns方法不生效的解决方案

    SpringBoot拦截器excludePathPatterns方法不生效的解决方案

    这篇文章主要介绍了SpringBoot拦截器excludePathPatterns方法不生效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • spring boot 使用 Kafka的场景分析

    spring boot 使用 Kafka的场景分析

    本文详细介绍了Kafka作为消息队列在SpringBoot中的使用方法,包括添加依赖、创建生产者和消费者,以及与RocketMQ的比较,着重于数据可靠性、性能和消息传递方式,还探讨了Kafka在实时数据流处理、事件驱动架构等场景的应用,感兴趣的朋友跟随小编一起看看吧
    2025-12-12
  • 区分java中String+String和String+char

    区分java中String+String和String+char

    这篇文章主要向大家详细区分了java中String+String和String+char,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • Sax解析xml_动力节点Java学院整理

    Sax解析xml_动力节点Java学院整理

    这篇文章主要介绍了Sax解析xml,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • IDEA中maven无法下载源码的解决方法

    IDEA中maven无法下载源码的解决方法

    这篇文章主要为大家详细介绍了当IDEA中maven无法下载源码时改如何解决,文中通过图文为大家进行了详细讲解,需要的小伙伴可以参考一下
    2023-08-08
  • mybatis实现表与对象的关联关系_动力节点Java学院整理

    mybatis实现表与对象的关联关系_动力节点Java学院整理

    这篇文章主要介绍了mybatis实现表与对象的关联关系_动力节点Java学院整理,需要的朋友可以参考下
    2017-09-09
  • Spring Batch实战示例

    Spring Batch实战示例

    批量数据处理是一个非常常见的需求,比如月底的工资代发、银行对账、数据报表生成等,当数据量达到几十万甚至上百万时,可以高效的完成,感兴趣的可以了解一下
    2026-02-02
  • Spring 父类变量注入失败的解决

    Spring 父类变量注入失败的解决

    这篇文章主要介绍了Spring 父类变量注入失败的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java实现简单连连看游戏

    Java实现简单连连看游戏

    这篇文章主要为大家详细介绍了Java实现简单连连看游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • 使用concurrentHashMap如何实现缓存

    使用concurrentHashMap如何实现缓存

    文章介绍了使用ConcurrentHashMap实现缓存的线程安全性和初始化方法,以及如何处理高并发场景下的缓存清理和数据一致性问题,包括分桶、使用ConcurrentLinkedQueue以及使用CountDownLatch来确保缓存数据的不丢失
    2025-02-02

最新评论