报错
报错内容如下
Expected one result (or null) to be returned by selectOne(), but found: 2
找原因
于是我就去看了一下源码
发现selectOne的实现是用的selectList查询到结果后在对list做判断
默认情况下如果list长度大于1就报错
default T selectOne(@Param("ew") Wrapper<T> queryWrapper, boolean throwEx) {
List<T> list = this.selectList(queryWrapper);
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: " + size);
} else {
return list.get(0);
}
} else {
return null;
}
}
解决方案
方案一
通过源码可以看出第二个参数可出传入false跳过这个错误
@Override
public User getUser(String username) {
User where = new User();
where.setUsername(username);
return userMapper.selectOne(new QueryWrapper<>(where), false);
}
方案二
但是selectList方式还是符合我的心理预期的
于是我在网上找到了第二种方法
就是在queryWrapper上加limit 1
@Override
public User getUser(String username) {
User where = new User();
where.setUsername(username);
QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(where);
userQueryWrapper.last("limit 1");
return userMapper.selectOne(userQueryWrapper);
}
方案三
虽然在queryWrapper上加手动加limit 1,但是要改的地方太多
于是可以使用切面来改进一下
@Aspect
@Component
public class MybatisAspect {
// 配置织入点
@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) {
((AbstractWrapper<?, ?, ?>) arg).last("limit 1");
}
}
}