尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

一次 MyBatis 统计查询引发的 ClassCastException:Long 不能强转为 Integer

一次 MyBatis 统计查询引发的 ClassCastException:Long 不能强转为 Integer
📅 发布时间:2026/7/31 10:04:35

关键词:MyBatis、ClassCastException、COUNT 聚合、类型映射、Spring Boot

一、问题的出现

在一个 Spring Boot + MyBatis 的报表统计接口中,调用ReportServiceIml.getEmpJobData()时,控制台抛出了如下异常:

java.lang.ClassCastException: class java.lang.Long cannot be cast to class java.lang.Integer at com.mlamp.service.impl.ReportServiceIml.lambda$getEmpJobData$1(ReportServiceIml.java:24) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)

报错位置指向第 24 行:

jobOption.setDataList(list.stream().map(m->(Integer)m.get("count")).toList());

异常堆栈很清晰地告诉我们:Long类型的对象无法被强转为Integer。

二、根因分析

1. MyBatis 对聚合函数结果类型的默认映射

我们的数据来自一条COUNT()聚合查询:

List<Map<String,Object>>list=empMapper.getJobList();

当查询结果以Map<String, Object>形式返回时,MyBatis 并不会把数据库字段"智能"地映射成你期望的类型,而是按照 JDBC 的默认规则转换:

SQL 类型示例MyBatis / JDBC 默认映射的 Java 类型
BIGINT自增主键、COUNT 结果Long
INT/INTEGER普通整型字段Integer
DECIMALSUM 金额等BigDecimal

注意:COUNT(*)、COUNT(1)这类聚合函数的返回类型在 JDBC 规范中是BIGINT,因此 MyBatis 会把它映射为Long,而不是Integer。

2. 为什么强转会失败?

Long和Integer都是Number的子类,彼此之间没有继承关系。Java 的强制类型转换((Integer) obj)是针对引用类型的,只有在对象的实际运行时类型与目标类型一致(或存在继承关系)时才能成功。把一个实际是Long的对象强转成Integer,JVM 在运行时就会抛出ClassCastException。

这与"自动拆箱 + 数值转换"是两回事。(int) longValue这种基本类型转换是合法的,但(Integer) (Long 对象)这种引用类型转换是不合法的。

3. 出错代码

// 字段实际上是一个 Long 对象jobOption.setDataList(list.stream().map(m->(Integer)m.get("count")).toList());

m.get("count")返回的是Long,再(Integer)强转,于是炸了。

三、解决方案

目标:把Long安全、明确地转换为int,再塞进List<Integer>。

方案一(推荐):Math.toIntExact

jobOption.setDataList(list.stream().map(m->Math.toIntExact((Long)m.get("count"))).toList());

Math.toIntExact(long)会把long转为int,并在数值超出int取值范围(-2^31 ~ 2^31-1)时主动抛出ArithmeticException。对统计数据量这种场景,这是一个安全的"早失败"保护。

方案二:直接调用intValue()

jobOption.setDataList(list.stream().map(m->((Long)m.get("count")).intValue()).toList());

简单直接,但数值溢出时不会报错(直接截断高位),适合你能确定数据量不会爆int范围的场景。

方案三(治本):从 SQL/结果类型上规避

如果希望从根源上得到Integer,可以在 Mapper 中:

  • 使用@MapKey或定义专门的 DTO/实体类,配合<result>明确指定jdbcType与javaType;
  • 或在 SQL 中使用CAST(COUNT(*) AS SIGNED)等(仍然建议接收端用Long,因为统计结果本就可能很大)。

一般来说,统计类结果用Long/BigDecimal接收是最稳妥的,上面的方案一/二足以应对绝大多数业务。

四、经验总结

  1. COUNT()、SUM()等聚合函数的结果,在 MyBatis 中通常映射为Long(BigDecimal),而不是Integer。
  2. Map<String, Object>接收查询结果时,要清楚每个字段的实际类型,不要凭直觉强转。
  3. 引用类型之间不能随意强转,Long/Integer没有继承关系,必须用数值转换方法(如intValue()、Math.toIntExact())。
  4. 涉及可能大数值的统计量,优先使用Long或BigDecimal承载,避免int溢出。

一个小小的统计接口,背后是对 JDBC 类型映射规则的理解偏差。把Long当Integer用,是 MyBatis 初学者最常见的坑之一,记住它,能省下不少排查时间。

相关新闻

  • 小米运动自动刷步数:5分钟搭建你的智能健康数据管家
  • 2026昭通黄金回收白银回收铂金回收市民首选无隐形扣费正规备案回收门店联系方式推荐
  • 基于Simulink的电机双环PI控制:从理论建模到仿真整定全流程

最新新闻

  • Source Han Serif思源宋体:免费开源中文字体终极指南 [特殊字符]
  • 深入理解 iOS 开发工具链 Cursor、Xcode、KXApp 全面对比与选择指南
  • 已经工作后考什么证比较好用?2026职场人破局的高含金量证书盘点
  • AI模型服务化架构评审必查清单(附GPT-4o实测验证):8类动态依赖陷阱及防御代码模板
  • 2026(新)金华 CMA 甲醛检测机构推荐:衡境测研等 5 家纯检测实验室 - 衡境测研
  • MS文件格式转换:从PDB到CIF与MOL的完整操作指南

日新闻

  • 7步掌握KMS智能激活工具:Windows和Office永久激活完整方案
  • 如何在Windows上运行iOS应用:ipasim跨平台模拟器终极指南
  • 2026年重庆工伤赔偿律师口碑推荐:洪家木律师用专业赢得信赖 - 本地品牌推荐

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号