在項目中我們經常會遇到這種需求:
根據一組 ID 查詢數據庫,并返回指定字段列表。
我在寫代碼的時候,遇到了一個典型的坑,分享出來給大家。
一、問題背景
我的代碼是這樣寫的(查詢項目表的負責人信息):
@PostMapping("/getOwnerInfoList")
public Result getOwnerInfoList(@RequestBody List<Integer> pcIds) {
List<Map<String, Object>> result = pmPcService.listObjs(
new LambdaQueryWrapper<PmPc>()
.select(PmPc::getPcId, PmPc::getOwnerUserId, PmPc::getDocumentCode)
.in(PmPc::getPcId, pcIds),
pc -> {
PmPc p = (PmPc) pc; // 👈 報錯點
Map<String, Object> map = new HashMap<>();
map.put("pcId", p.getPcId());
map.put("ownerUserId", p.getOwnerUserId());
map.put("documentCode", p.getDocumentCode());
return map;
}
);
return R.ok(result);
}
結果運行時直接報錯:
java.lang.ClassCastException: java.lang.Integer cannot be cast to com.kakarote.pm.entity.PO.PmPc
二、原因分析
問題的關鍵在于 listObjs
方法的返回值。
listObjs
的官方說明是:
查詢并返回對象集合,默認只會返回查詢結果的 第一列。
也就是說,如果你 select
了三列(pcId, ownerUserId, documentCode
),listObjs
默認只返回第一列 pcId
。
所以 pc
其實是 Integer
,你強轉成 PmPc
就會報 ClassCastException
。
如果你寫了 resultHandler 回調,查詢多列時返回的是 Object[]
,而不是實體對象。
三、正確的解決方案
?方式一:直接用 list
最簡單的方式就是不用 listObjs
,而是用 list
,這樣返回的就是實體對象
List<PmPc> list = pmPcService.list(new LambdaQueryWrapper<PmPc>().select(PmPc::getPcId, PmPc::getOwnerUserId, PmPc::getDocumentCode).in(PmPc::getPcId, pcIds)
);List<Map<String, Object>> result = list.stream().map(p -> {Map<String, Object> map = new HashMap<>();map.put("pcId", p.getPcId());map.put("ownerUserId", p.getOwnerUserId());map.put("documentCode", p.getDocumentCode());return map;
}).collect(Collectors.toList());return R.ok(result);
方式二:繼續用 listObjs
如果一定要用 listObjs
,正確寫法如下:
List<Map<String, Object>> result = pmPcService.listObjs(new LambdaQueryWrapper<PmPc>().select(PmPc::getPcId, PmPc::getOwnerUserId, PmPc::getDocumentCode).in(PmPc::getPcId, pcIds),obj -> {Object[] arr = (Object[]) obj; // listObjs 查詢多列時返回 Object[]Map<String, Object> map = new HashMap<>();map.put("pcId", arr[0]);map.put("ownerUserId", arr[1]);map.put("documentCode", arr[2]);return map;}
);
四、總結
listObjs
默認只返回第一列,別以為它能直接返回實體。如果你需要實體對象,用
list
更直觀。如果你需要自定義對象,用
listObjs
+Object[]
來處理。
💡 推薦:
如果業務中經常要查多列 → 用 list
;
如果只查單列(比如只查 id
列表) → 用 listObjs
。