必须将com.mysql.jdbc.Driver全部替换为com.mysql.cj.jdbc.Driver,升级驱动至mysql-connector-j-8.3.0+,并配置完整连接参数:serverTimezone、characterEncoding、useSSL=false和allowPublicKeyRetrieval=true。

com.mysql.jdbc.Driver 报 ClassNotFoundException 怎么办
这个类在 MySQL 8.0+ 的驱动里根本不存在了。老项目里硬编码、application.yml 或 db.properties 中写的 com.mysql.jdbc.Driver 必须全部替换成 com.mysql.cj.jdbc.Driver。
检查 classpath 下的 JAR 名:必须是 mysql-connector-j-8.x.x.jar(推荐 8.3.0+),不能是 mysql-connector-java-5.1.49.jar 这类旧包。
- 删掉 Maven 中所有
mysql-connector-java5.x 依赖,换成:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.3.0</version> </dependency>
- 代码里调用
Class.forName("com.mysql.jdbc.Driver")的地方,直接删掉——新驱动通过 SPI 自动注册,手动加载反而可能触发警告
连接能建但查不出数据或报时区/字符集错
只换驱动类名远远不够。MySQL 8.0 默认强制校验时区、默认用 utf8mb4、默认要求 SSL,老连接串缺参数会导致静默失败:应用能启动、Connection 对象能创建,但第一次 executeQuery 就卡住或返回空结果。
完整连接 URL 至少要带这四个参数:?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
-
serverTimezone不能留空或写UTC就完事——业务时间逻辑依赖本地时区,Asia/Shanghai更稳妥 -
characterEncoding=utf8不是可选:虽然 MySQL 8.0 默认是utf8mb4,但驱动不声明会把某些中文字段截断或报Incorrect string value -
useSSL=false在开发环境必须加;生产环境应配证书并设为true,否则连接可能被拒绝 -
allowPublicKeyRetrieval=true是 8.0.4+ 强制要求,否则 RSA 密钥交换阶段就卡死
Navicat / DBeaver / FineReport 等工具连不上
这些工具自带的 JDBC 驱动版本往往滞后(比如 Navicat 16 内置的是 mysql-connector-java-8.0.11.jar),遇到 MySQL 8.0.33+ 的 caching_sha2_password 认证协议时,会直接报 Public Key Retrieval is not allowed 或 Unknown system variable 'caching_sha2_password'。
手动替换是最直接有效的绕过方式:
- 关闭所有工具进程(包括后台托盘)
- 找到安装目录下的
drivers子目录(如C:\Program Files\PremiumSoft\Navicat Premium 16\drivers) - 备份原
mysql.jar,下载官方mysql-connector-j-8.3.0.jar,重命名为mysql.jar并覆盖 - 重启工具,新建连接时认证方式会自动适配,不再需要勾选“允许公钥检索”
如果仍报 Client does not support authentication protocol,说明用户账户还在用旧插件,需在 MySQL 中执行:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES;
MyBatis 分页 / IN 查询失效或返回空结果
这不是 SQL 写错了,是预编译语句缓存行为变了。老驱动默认开启 cachePrepStmts=true,新驱动不显式配置缓存大小时会降级为禁用,导致 ORM 动态 SQL 回退成普通语句执行,触发权限限制或语法不兼容。
在连接 URL 中补上:
&cachePrepStmts=true&prepStmtCacheSize=250&prepStmtCacheSqlLimit=2048
- 不加这些参数,
IN (?, ?, ?)类型的动态查询可能被当作非预编译语句处理,尤其在WHERE id IN (#{ids})场景下容易出问题 - MyBatis 的分页插件(如 PageHelper)依赖预编译行为做 SQL 改写,缓存关闭后改写逻辑可能失效
真正麻烦的不是驱动换不换,而是不同客户端对同一套参数的敏感度差异——比如 FineReport 要求 validationQuery=SELECT 1,而 DataX 任务失败日志里那个 “Could not retrieve transaction read-only status server” 其实就是驱动没认出 MySQL 8.0 新增的事务状态字段。这类问题不会报错在连接阶段,而是藏在第一次执行时,得盯紧实际 SQL 执行路径才能定位。



















