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");