当前位置: 首页 > news >正文

SpringBoot + MyBatis-Plus 使用 listObjs 报 ClassCastException 的原因与解决办法

在项目中我们经常会遇到这种需求:
根据一组 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

http://www.dtcms.com/a/340278.html

相关文章:

  • Rabbit 实战指南-学习笔记
  • HTML+CSS:浮动详解
  • 3D文档控件Aspose.3D实用教程:使用 C# 构建 OBJ 到 U3D 转换器
  • awk 基础用法示例
  • 测试DuckDB插件对不同格式xlsx文件的读写效率
  • MyCAT分库分表
  • Go特有的安全漏洞及渗透测试利用方法(通俗易懂)
  • 次短路P2865 [USACO06NOV] Roadblocks G题解
  • SLAM文献之-Globally Consistent and Tightly Coupled 3D LiDAR Inertial Mapping
  • RESP协议
  • React响应式链路
  • SCAU学习笔记 - 自科三面前端方向实战演示
  • 157-基于Python的懂车帝汽车数据爬虫分析与可视化系统
  • NVIDIA Isaac Sim
  • Ubuntu 主机名:精通配置与管理
  • 全球首款 8K 全景无人机影翎 A1 发布解读:航拍进入“先飞行后取景”时代
  • 从 “模仿” 到 “创造”:AI 大模型的 “思维进化” 背后,技术突破在哪?
  • 沪深股指期货指数「IF000」期货行情怎么看?
  • 利用无事务方式插入数据库解决并发插入问题(最小主键id思路)
  • 海外短剧app、h5、独立站、国内短剧看广告app,短剧小程序、源码交付开发
  • java17学习笔记
  • RK android14 Setting一级菜单IR遥控器无法聚焦问题解决方法
  • VPS海外节点性能监控全攻略:从基础配置到高级优化
  • 02-docker相关知识
  • Java 学习笔记(基础篇6)
  • 29.Linux rsync+inotify解决同步数据实时性
  • 【Tech Arch】Apache HBase分布式 NoSQL 数据库
  • 签名应用APP分发平台的微服务化部署是什么?其有哪些优势?
  • 微服务自动注册到ShenYu网关配置详解
  • mysql数据恢复