个人技术分享

今天遇到一个问题

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

74ec03671dc248d6983d0d9d5be45f8e.png d88a90ec814f4316a3aef75be6c1598c.png

 9c6150c3c9494067bc34013b6e01f08e.png

 

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

这个里面的东西就是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;
    }
  }

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

 

 问题来源:

java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条_编程语言-CSDN问答