mysql 8.0+ 彻底弃用 com.mysql.jdbc.driver,必须升级驱动至 mysql-connector-java-8.x.x.jar 并将类名改为 com.mysql.cj.jdbc.driver,同时连接串需补全 servertimezone、characterencoding、usessl=false 和 allowpublickeyretrieval=true 等参数。

com.mysql.jdbc.Driver 报 ClassNotFoundException 就是驱动没换对
MySQL 8.0 彻底弃用了 com.mysql.jdbc.Driver,老项目里硬编码或配置文件中还写这个类名,启动时直接抛 ClassNotFoundException。这不是类路径没加对,而是这个类在 mysql-connector-java-8.x.x.jar 里根本不存在了。
检查你项目里的 JDBC 驱动 JAR 文件名:mysql-connector-java-5.1.49.jar 或类似 5.x 版本必须全部替换成 mysql-connector-java-8.0.33.jar(或更高,如 8.3.x);Maven 依赖要删掉旧版,加上:
<dependency><groupid>mysql</groupid><artifactid>mysql-connector-java</artifactid><version>8.3.0</version></dependency>
- Spring Boot 2.1+ 默认带 8.x 驱动,但若你在
pom.xml中显式<exclusions></exclusions>掉了它,又手动引入了 5.x,照样报错 - 代码里调用
Class.forName("com.mysql.jdbc.Driver")的地方,必须改成Class.forName("com.mysql.cj.jdbc.Driver") - 配置文件(如
application.yml)中的driver-class-name: com.mysql.jdbc.Driver同样要改
连接串缺 serverTimezone 导致启动不报错但查不出数据
只改驱动类名还不够。mysql-connector-java-8.x 默认强制校验服务端时区,而 MySQL 5.7 时代很多连接串只写 ?useSSL=false,到了 8.0 就会静默失败——应用能启动、连接对象创建成功,但第一次执行 SELECT 就卡住或返回空结果,日志里可能只有模糊的 SQLNonTransientConnectionException。
完整连接参数必须包含时区和字符集声明:
jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
-
serverTimezone必须显式指定,不能留空或用系统默认值;UTC虽可通,但业务时间逻辑容易出错,建议用实际部署时区如Asia/Shanghai -
characterEncoding=utf8是为了兼容老 SQL 模板,虽然 MySQL 8.0 默认用utf8mb4,但驱动不加此参数可能在某些字符串操作中触发Incorrect string value -
useSSL=false在开发环境必须加;生产环境应配证书并设为true,否则连接可能被拒绝 -
allowPublicKeyRetrieval=true是 8.0.4+ 强制要求,否则 RSA 密钥交换阶段会直接中断
caching_sha2_password 认证失败不是数据库配错了
连上就报 Authentication plugin 'caching_sha2_password' cannot be loaded 或 Public Key Retrieval is not allowed,别急着去 MySQL 里执行 ALTER USER ... IDENTIFIED WITH mysql_native_password。这说明驱动版本是对的,但认证流程卡在插件协商环节。
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
根本原因:旧版客户端(比如 DBVisualizer 自带的老驱动、某些 IDE 内置数据库工具)即使用了 8.x JAR,也可能未启用新认证协议支持。此时关键不是改数据库用户,而是确认驱动行为:
- 确保连接 URL 中已含
allowPublicKeyRetrieval=true—— 缺这个参数,caching_sha2_password握手无法完成 - 如果仍失败,且你确定不能升级客户端工具(如固定版本的 Navicat),才考虑临时改用户插件:
ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'pass'; - 云数据库(如阿里云 RDS、腾讯云 CDB)通常不允许执行
ALTER USER ... IDENTIFIED WITH,这时唯一解法就是升级客户端驱动或换工具
cachePrepStmts 和 prepStmtCacheSize 影响 MyBatis 动态 SQL 执行
应用启动成功、查询单条记录也正常,但一跑分页或 IN (?, ?, ?...) 列表就报错或返回空,常见于 MyBatis 场景。这不是 SQL 写错了,而是 Connector/J 8.x 对预编译语句缓存策略变了。
老驱动默认开启 cachePrepStmts=true,新驱动在未显式配置时会禁用缓存,导致部分动态 SQL 回退到非预编译模式,触发权限限制或语法不兼容(比如长 IN 列表被截断)。
补上这两项参数能稳定行为:
&cachePrepStmts=true&prepStmtCacheSize=250&prepStmtCacheSqlLimit=2048
-
cachePrepStmts=true显式启用缓存 -
prepStmtCacheSize=250设合理大小,避免频繁重建 PreparedStatement -
prepStmtCacheSqlLimit=2048确保较长的动态 SQL(如多条件拼接的 WHERE)也能进缓存 - 不加的话,MyBatis 的
<foreach></foreach>、JPA 的批量插入等都可能异常
真正麻烦的从来不是换一个 JAR 或改一行配置,而是多个参数必须同时生效——少一个,错误现象就变个样,排查时容易误判方向。尤其当项目混用多种数据库工具(IDE 内置、DBVisualizer、命令行)时,每个工具的驱动版本和连接参数都得单独核对。










