MySQL 8.0+ 连接失败主因是驱动类和参数不兼容:必须将 com.mysql.jdbc.Driver 替换为 com.mysql.cj.jdbc.Driver,使用 mysql-connector-j-8.x.jar,并在连接串中补全 serverTimezone、characterEncoding、useSSL=false 和 allowPublicKeyRetrieval=true。
MySQL 升级到 8.0+ 后连不上,90% 是因为还在用 mysql-connector-java-5.x 驱动或没改连接参数——不是数据库配错了,是客户端协议和认证方式已经不兼容。
这个类在 MySQL 8.0+ 的驱动里根本不存在了。老项目里硬编码、application.yml 或 db.properties 中写的 com.mysql.jdbc.Driver 必须全部替换成 com.mysql.cj.jdbc.Driver。
mysql-connector-java-8.x.x.jar 或 mysql-connector-j-8.x.x.jar(8.3.0+ 推荐),不能是 mysql-connector-java-5.1.49.jar 这类<dependency><br> <groupId>mysql</groupId><br> <artifactId>mysql-connector-j</artifactId><br> <version>8.3.0</version><br></dependency>
Class.forName("com.mysql.jdbc.Driver") 的地方,直接删掉——新驱动通过 SPI 自动注册,手动加载反而可能触发警告只换驱动类名远远不够。MySQL 8.0 默认强制校验时区、默认用 utf8mb4、默认要求 SSL,老连接串缺参数会导致静默失败:应用能启动、Connection 对象能创建,但第一次 executeQuery 就卡住或返回空结果。
?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 密钥交换阶段就卡死这不是 SQL 写错了,是预编译语句缓存行为变了。老驱动默认开启 cachePrepStmts=true,新驱动不显式配置缓存大小时会降级为禁用,导致 ORM 动态 SQL 回退成普通语句执行,触发权限限制或语法不兼容。
&cachePrepStmts=true&prepStmtCacheSize=250&prepStmtCacheSqlLimit=2048
IN (?, ?, ?...) 列表过长、LIMIT ?,? 分页等场景,不加可能直接返回空集合spring-boot-starter-jdbc 2.1+ 虽默认带 8.x 驱动,但若你 <exclusions> 掉它又手动引入了 5.x,照样踩坑这是 MySQL 8.0 默认认证插件变更导致的。JDBC 5.x、旧版 Navicat、DBeaver 等客户端根本不认识 caching_sha2_password,哪怕驱动和 URL 都对,也会在登录阶段拒连。
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES;
my.cnf 的 default_authentication_plugin:只影响新用户,已存在的用户不会自动更新,且重启服务有风险allowPublicKeyRetrieval=true 就能绕过”的说法——它解决的是密钥交换问题,不是认证插件不识别问题真正麻烦的点不在驱动换没换,而在于每个参数改动都可能引发连锁反应:比如 useSSL=false 解决了连接,却让某些安全扫描工具直接标红;serverTimezone=Asia/Shanghai 解决了时间错乱,但在跨时区部署时又得动态切换。这些细节不写进配置、不验证到真实查询,光靠启动日志是看不出问题的。