前提:MySQL 8.0 两大账号认证插件
mysql_native_password:兼容老驱动,无 RSA/SSL 强制要求
caching_sha2_password:8.0 默认,分SSL 链路、裸 TCP+RSA 公钥两种场景驱动版本说明:
MySQL8 推荐驱动:
mysql-connector-java 8.x(包名已改成com.mysql.cj.jdbc.Driver,不再是com.mysql.jdbc.Driver,旧类名已废弃)Maven 坐标:
<!-- mysql connector 8.x -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
一、配置总览对比表
公共必带参数(8.0 强制,不加会抛时区异常)
serverTimezone=Asia/ShanghaicharacterEncoding=utf8mb4
二、三种完整配置示例(SpringBoot+MyBatis,application.yml)
场景 1:账号使用 mysql_native_password(兼容旧认证)
账号 SQL:
ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'Pass@123456';
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test_db?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8mb4
username: user
password: Pass@123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.xxx.entity
✅ 特点:
驱动不需要处理 RSA;
老项目从 5.7 迁移最简单,不会报认证协议错误; ❌ 缺点:密码哈希算法安全弱,只是临时兼容方案。
场景 2:caching_sha2_password + SSL 加密连接【生产首选】
新建用户默认就是这个插件,MySQL 开启 SSL。
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test_db?useSSL=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8mb4
username: user
password: Pass@123456
driver-class-name: com.mysql.cj.jdbc.Driver
校验 MySQL 是否开启 SSL:登录 MySQL 执行
SHOW VARIABLES LIKE '%ssl%';
✅ 优点:密码在 SSL 加密通道传输,不需要 RSA 公钥相关参数,没有中间人风险。
场景 3:caching_sha2_password,不启用 SSL(内网测试场景)
方案 3.1:自动拉取公钥 allowPublicKeyRetrieval=true(仅测试)
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test_db?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8mb4&allowPublicKeyRetrieval=true
username: user
password: Pass@123456
driver-class-name: com.mysql.cj.jdbc.Driver
⚠️ 风险重点: allowPublicKeyRetrieval=true 允许客户端从网络动态获取 MySQL 服务端 RSA 公钥,中间人可以劫持连接返回伪造公钥,窃取密码,生产严禁开启。
方案 3.2:本地指定 RSA 公钥文件(内网无 SSL,安全备选)
从 MySQL 服务器导出公钥(MySQL8 默认生成密钥对)
SELECT @@sha256_password_public_key;
复制公钥保存为 public_key.pem,放到应用服务器。 2. JDBC 配置:
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test_db?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8mb4&serverRsaPublicKeyFile=/opt/app/public_key.pem
username: user
password: Pass@123456
driver-class-name: com.mysql.cj.jdbc.Driver
客户端不会从网络拉公钥,使用本地文件,规避中间人劫持风险。
三、MyBatis 本身有没有特殊配置?
MyBatis 不感知 MySQL 认证插件! MyBatis 是基于 JDBC 的持久层框架,认证逻辑全部在 MySQL JDBC 驱动内部完成,MyBatis 只负责 SQL 映射。
只要 JDBC 连接串正确,MyBatis 不需要任何额外修改;连接报错根源全部在驱动和账号认证插件不匹配。
四、常见报错与排查
报错 1:Client does not support authentication protocol requested by server
原因:账号是caching_sha2_password,使用了过低版本 JDBC 驱动(5.x)。 解决:升级驱动到 8.x,或者修改账号为mysql_native_password。
报错 2:Public key retrieval is not allowed
原因:caching_sha2_password,无 SSL 连接,没配置allowPublicKeyRetrieval,也没有指定serverRsaPublicKeyFile。 解决:测试环境加allowPublicKeyRetrieval=true;生产启用 SSL。
报错 3:时区异常 The server time zone value 'CST' is unrecognized or represents more than one time zone
原因:缺少 serverTimezone=Asia/Shanghai,8.x 驱动强制要求。
五、迁移选型建议
新项目 MySQL8:保持默认
caching_sha2_password,开启 SSL 连接,不要用 allowPublicKeyRetrieval老系统从 5.7 迁移,短期内不改代码:账号临时改成
mysql_native_password,长期逐步迁移到 caching_sha2_password+SSL公网访问 MySQL8:必须 SSL,绝对禁止裸 TCP+allowPublicKeyRetrieval
六、原生 JDBC 纯代码示例(便于理解底层)
String url = "jdbc:mysql://127.0.0.1:3306/test_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";
String user = "user";
String pwd = "Pass@123456";
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, pwd);