xx群 :应该怎么优雅的查询其中一个结果呢 selectOne。我看底层 false会调用 selectList。
MP的BaseMapper封装了多种快捷常用查询。
selectList比较好理解。
selectOne,有点争议。
既然是selectOne,查询1个,但这个是大众理解的“查询1个就行”,还是 数学上的“查询一个且只能查询一个”。
严格意义上的selectOne,BaseMapper中的接口定义。
/**
* 根据 entity 条件,查询一条记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
它的内部实现源码没有找到。
如果有多个,会抛出异常,这是合理的。
查询一个,却存在多个,这种情况,通用的技术组件,是不明确怎么处理的。
抛出异常,让上层去处理。
对比着看ServiceImpl的getOne封装。
@Override
public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
if (throwEx) {
return baseMapper.selectOne(queryWrapper);
}
return SqlHelper.getObject(baseMapper.selectList(queryWrapper));
}
如果需要抛异常,默认情况,就原封不动调用mapper的封装。
否则,调用 mapper层的selectList,先查询出多个,再获得1个。
/**
* 从list中取第一条数据返回对应List中泛型的单个结果
*
* @param list ignore
* @param <E> ignore
* @return ignore
*/
public static <E> E getObject(List<E> list) {
if (CollectionUtils.isNotEmpty(list)) {
int size = list.size();
if (size > 1) {
logger.warn(String.format("Warn: execute Method There are %s results.", size));
}
return list.get(0);
}
return null;
}
取第1条数据。
从查询结果中,取得第1条,这个显然好理解。
问题是,数据库中存在A1、A2、A3 3条 符合条件的数据的时候,list中的第1条是3个中的哪一个呢?
显然不清楚了。
这个取决于 list方法,有没有排序。
如果没有指定排序字段,默认是 按照 主键 升序的。
select * from config where config_group = "contract-type";
结论:
1、如果确定应该只有1个
getOne(queryWrapper, true);
2、如果可能有多个,但不在意 区别
比如,根据公司名查找一个公司,看看这个公司是否存在,随便取1个都行。
getOne(queryWrapper, false);
3、如果可能有多个,但在意区别
比如,根据公司名搜索公司,查询他最近1次的记录。
queryWrapper.setOrderByDesc("timeField");
getOne(queryWrapper, false);
相反的情况也比较常见,取最早第1次的记录。
queryWrapper.setOrderByAsc("timeField");