Mybatis-plus解决selectOne查询多个会报错的问题

解决Mybatis-plus的BaseMapper的selectOne查询多个会异常的问题优化

一、前言

在使用Mybatis-plus所提供的SelectOne方法时候存在一个问题,就是如果查询匹配到的数据是多个的话会报如下异常:

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

其实这个并不算是错误的情况,但是在编程的时候有时我的业务会有要求即便是有重复的情况下也应该返回数据,哪怕的是默认的。其实这种业务场景并不常见。
但是如果有这种需求的小伙伴可以从下面的方式进行优化。

二、解决方案

通过使用切面进行解决AOP。

如果我们希望使用Mybatis-plus的单表操作功能,我们需要将自己Mapper层接口去继承BaseMapper,从而实现简单的单表操作。例如:

public interface RoleMapper extends BaseMapper<Role> {
}

之后我们加入以下AOP配置文件:

@Aspect
@Component
public class MybatisAspectj {

    // 配置织入点
    @Pointcut("execution(public * com.baomidou.mybatisplus.core.mapper.BaseMapper.selectOne(..))")
    public void selectOneAspect() {
    }

    @Before("selectOneAspect()")
    public void beforeSelect(JoinPoint point) {
        Object arg = point.getArgs()[0];
        if (arg instanceof AbstractWrapper) {
            arg = (AbstractWrapper) arg;
            ((AbstractWrapper) arg).last("limit 1");
        }
    }
}

之后就没有问题了。

原理:

这个解决方案的原理比较简单,其实就是对SelectOne参数列表的Wrapper对面默认加上一个自定义的条件limit 1,实现只查一条。至于加上limit 1之后是有很多优点的,详情可以看MYSQL 查询单一数据优化
这篇博客。

测试:

我新建了一个只含Role表的数据库,去查询只有"角色"的实体。:

idname
1测试角色1
2角色2

注意:此处环境已经加上了上述AOP配置

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SelectOneTest {

    @Autowired
    private RoleMapper roleMapper;

    @Test
    public void selectRole() {
    	
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<Role>().like(Role::getName, "角色");
        List<Role> roles = roleMapper.selectList(wrapper);
        System.out.println("SelectList==查询name中有‘角色’的数据:");
        System.out.println(roles);
        System.out.println("SelectOne==查询name中有‘角色’的数据:");
        Role role = roleMapper.selectOne(wrapper);
        System.out.println(role);
    }
}

结果:

在这里插入图片描述

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值