mybatis-plus中使用QueryWrapper和LambdaQueryWrapper的limit出现的问题

在使用mybatis-plus的QueryWrapper和LambdaQueryWrapper时,遇到当查询结果超过1条时抛出TooManyResultsException异常。问题在于last()方法的sql没有被正确拼接。解决方案包括:将last()独立写在最后,避免使用LambdaQueryWrapper的lambda方法,或直接使用LambdaQueryWrapper进行操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在项目中遇到个比较奇怪的问题,使用QueryWrapper查询一条数据时,如果表中有大于1条命中,则会报:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2 异常。

代码如下:

QueryWrapper<Crm> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Crm::getShopId, cdtShopId)
                .orderByDesc(Crm::getId).last(" limit 1");
        return baseMapper.selectOne(queryWrapper);

照常说上面代码会变成下面的sql

SELECT * FROM crm WHERE shopId = ? ORDER BY id DESC limit 1 

但实际上跑出来的结果是没有加上最后的limit 1
经过不断测试得知:使用QueryWrapper的lambda()方法时,会new一个LambdaQueryWrapper返回,这时候直接在eq()、orderByDesc()后面使用last()并不会把last()中的sql拼接到sql后面

 public LambdaQueryWrapper<T> lambda() {
        return new LambdaQueryWrapper<>(entity, entityClass, sqlSelect, paramNameSeq, paramNameValuePairs, expression);
    }

原因有可能是下图所示,last()使用的是LambdaQueryWrapper的last,而selectOne()使用的是QueryWrapper对象分开写,具体原因还在查,后续再加上

在这里插入图片描述
分开写后的last()是QueryWrapper
在这里插入图片描述

解决这个问题有几个办法
1.last()不直接在eq()、orderByDesc()后面使用,继续使用QueryWrapper的last():

QueryWrapper<Crm> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Crm::getShopId, cdtShopId)
                .orderByDesc(Crm::getId);
        queryWrapper.last(" limit 1");
        return baseMapper.selectOne(queryWrapper);

2.QueryWrapper不使用lambda:

QueryWrapper<Crm> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shopId", cdtShopId)
                .orderByDesc("Id").last(" limit 1");
        return baseMapper.selectOne(queryWrapper);

3.直接使用LambdaQueryWrapper:

LambdaQueryWrapper<Crm> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Crm::getShopId, cdtShopId)
                .orderByDesc(Crm::getId).last(" limit 1");
        return baseMapper.selectOne(queryWrapper);

以上三种方法都可

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值