news 2026/10/21 6:14:30

MySQL 8.0 JDBC驱动Jar包实战:下载、配置与排错指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL 8.0 JDBC驱动Jar包实战:下载、配置与排错指南

“MySQL 8.0版本JDBC驱动Jar包”,这听起来像是一个非常小的技术问题,但实际情况是,我亲眼见过不止一个项目在数据库从5.7升级到8.0之后,应用层迟迟起不来,最后定位到的原因就是这个驱动Jar包没有换对。更夸张的是,有的人明明换了8.0的Jar,写连接串的时候还照着老文档抄,照样报错。这篇文章不绕弯子,直接把MySQL 8.0版本的JDBC驱动从下载、引入、配置到排错讲完,适合正在升级数据库、新建项目选型或者只是想把驱动换新的人。

1. 先搞明白:为什么MySQL 8.0的驱动和以前不是一回事

1.1 驱动类名变了,老一套直接失效

在MySQL 5.x时代,大家写JDBC连接的时候固定两行代码:

Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/testdb?useSSL=false&characterEncoding=utf8", "root", "123456");

这个com.mysql.jdbc.Driver是MySQL 5.x以及更早版本驱动的主类名。到了MySQL 8.0,官方把驱动类迁移到了com.mysql.cj.jdbc.Driver,这个包名是带cj的,含义就是“Connector/J”的新版实现。如果你只换了Jar包,但是代码里的Class.forName还写着老名字,程序启动时大概率会抛ClassNotFoundException,虽然8.0驱动为了兼容还在驱动Jar里保留了旧类的引用,但会打出弃用警告,而且某些框架的自动检测逻辑会因此走弯路,所以不要觉得能跑就是没问题。

需要说明的是,现在JDBC 4.0以上的规范支持DriverManager自动加载驱动,很多场景下可以省略Class.forName,但如果你用的还是老项目、老代码风格,请老老实实把类名改成com.mysql.cj.jdbc.Driver。

1.2 8.0驱动的坐标也变了,Maven依赖容易抄错

这是另一个非常容易踩的坑。如果你去Maven中央仓库搜索“mysql-connector-java”,会发现老坐标:

<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency>

这个坐标在8.0.33之后基本停止更新了。官方从8.0.31左右开始推荐新坐标:

<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> </dependency>

再往后,8.1、8.2、8.3、8.4这些版本,都只有com.mysql:mysql-connector-j这个新坐标。我建议你从现在开始统一使用新坐标,因为旧坐标未来不会再收到更新,而且新坐标和旧坐标在同一个版本号上的Jar内容基本一致,没什么理由继续守着旧的写错。

2. 获取MySQL 8.0 JDBC驱动Jar包的几种方式

2.1 最推荐:通过Maven或Gradle管理依赖

不管你是Spring Boot项目还是普通Java工程,我都推荐用构建工具来管理驱动包,而不是手工下载Jar。手工下载的问题很明显:版本容易记错、团队其他人拿到的是不是同一个版本没保证、升级的时候还要重新替换。用Maven就一行:

<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.4.0</version> </dependency>

Gradle对应的写法:

implementation 'com.mysql:mysql-connector-j:8.4.0'

这里顺便提一下版本选择。如果你追求稳定,我推荐8.0.33加上配置里的serverTimezone、useSSL、allowPublicKeyRetrieval参数,后面会讲。如果想用更新的LTS,可以关注8.4.x。不要盲目追求最新版本,因为驱动版本太新时,如果连接的是老版本MySQL服务器,某些行为差异可能会让你排查半天。

2.2 非Maven项目:直接下载Jar文件

有些老项目用Eclipse或IDEA管理,没有引入Maven,这种时候就得直接下载Jar包。打开Maven中央仓库的搜索页面,搜mysql-connector-j,然后选择你需要的版本,下载.jar文件即可。文件大小大概2MB多,不算大。

下载完之后,在IDEA里把Jar文件拷到项目根目录下新建的lib文件夹,然后右键Jar包选择“Add as Library”,搞定。Eclipse用户则在项目属性里的“Java Build Path”中添加外部Jar。我这里想多说一句:用这种方式管理依赖的团队,我强烈建议把Jar包放到一个统一的目录中,并且在项目文档里记录版本号,否则半年之后没人记得当前用的具体是什么版本,排查问题时就会很痛苦。

2.3 离线环境怎么搬驱动

有的公司生产网段和公网是隔离的,开发机上不能直接去中央仓库拉依赖,这时候需要提前把Jar包准备好。你可以在一台能联网的机器上通过Maven命令把Jar以及依赖一次性拉下来:

mvn dependency:get -Dartifact=com.mysql:mysql-connector-j:8.0.33

或者直接用浏览器下载Jar文件,拷贝到离线环境的本地仓库目录~/.m2/repository/com/mysql/mysql-connector-j/8.0.33/下。注意:如果用的是mysql-connector-java旧坐标,目录是mysql/mysql-connector-java,别放错位置。离线环境最容易出现的问题就是“我明明放了Jar,怎么还是ClassNotFound”,多半是放到了错误坐标对应的目录,Maven找不到,所以请务必检查本地仓库中的路径是否和GAV完全对应。

3. 连接串与核心参数设置,直接决定能不能连上

3.1 URL格式和驱动类名对照

MySQL 8.0驱动的URL格式整体还是:

jdbc:mysql://主机:端口/数据库名?参数1=值1&参数2=值2

端口默认3306,数据库名可写可不写。关键区别体现在参数上。一个典型的、能稳定连接MySQL 8.0的URL如下:

jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true

有人会发现,以前5.x时代不写serverTimezone和allowPublicKeyRetrieval也能连上,为什么到了8.0就必须加?因为MySQL 8.0的默认认证插件变成了caching_sha2_password,和5.x时代的mysql_native_password不一样。当客户端没有使用SSL连接时,如果服务器需要返回公钥来走RSA加密传输密码,JDBC驱动默认不允许直接向服务器请求公钥,所以会报“Public Key Retrieval is not allowed”,这时候就需要显式设置allowPublicKeyRetrieval=true。

3.2 三个最容易出错的参数:serverTimezone、useSSL、allowPublicKeyRetrieval

serverTimezone

驱动拿到数据库连接后,会读取服务器时区来决定JDBC层的时间转换行为。如果MySQL服务器时区设置为CST或者SYSTEM(代表系统时区),而驱动无法解析,就会出现:

The server time zone value 'CST' is unrecognized or represents more than one time zone.

解决办法有两个,我更推荐在URL里显式指定:

serverTimezone=Asia/Shanghai

注意不要写GMT+8这种带加号的形式,URL中+会被解析成空格。当然你也可以修改MySQL服务器的global time_zone,但那会影响所有客户端,属于数据库端改动,很多时候没法按你的意愿来。所以还是靠JDBC参数解决最灵活。

useSSL

MySQL 8.0驱动默认useSSL=true,但如果你连的是内网数据库,而且没有配置证书,就会看到一串WARN日志,大意是不验证服务器身份就建立了SSL连接。这种警告不会让程序挂掉,但会让人觉得不安心。最省事的办法就是:

useSSL=false

如果你的公司要求数据库连接必须走加密,那就不要设置false,而是应该在数据库端配置好证书,然后在JDBC URL里指定sslMode=VERIFY_CA以及trustCertificateKeyStoreUrl等参数。对于绝大多数内部应用来说,内网直连加上useSSL=false是常见的最简方案。

allowPublicKeyRetrieval

前面已经提过,这个参数主要是配合caching_sha2_password认证插件使用。如果你的MySQL 8.0用户采用的还是mysql_native_password,不设置也可以;但既然数据库都升级到8.0了,我建议直接设置allowPublicKeyRetrieval=true,避免未来用户更换认证插件时又突然连不上。

3.3 连接池场景下的驱动配置

现在大多数应用不会直接用DriverManager.getConnection,而是通过HikariCP、Druid或者DBCP拿连接。这时候有两点容易搞混:

  • Spring Boot 2.x及以上版本如果没有手动指定,会通过自动检测找到驱动,但如果你配置了spring.datasource.driver-class-name,请一定写新类名:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true spring.datasource.username=root spring.datasource.password=123456
  • 在HikariCP的Java配置中,一定要把URL放到jdbcUrl而不是url里,否则HikariCP不会用你的值。如下:
HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"); config.setUsername("root"); config.setPassword("123456"); config.setDriverClassName("com.mysql.cj.jdbc.Driver");

这也是很多Spring Boot项目“配了URL但连不上”的经典原因之一。

4. 从零接入一个项目的完整操作流程

4.1 Spring Boot项目实战

假设你新建了一个Spring Boot项目,要连接MySQL 8.0,完整步骤如下。

第一步,在pom.xml中引入依赖。如果项目继承自spring-boot-starter-parent,你甚至可以不写版本号,直接靠Spring Boot的依赖管理决定:

<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency>

注意scope=runtime。很多人喜欢把驱动放在compile作用域,也没有大问题,但runtime更语义化,因为你的代码通常不会直接引用驱动类。

第二步,在application.yml里配置数据源:

spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true username: root password: "你的密码"

第三步,启动项目并观察日志。正常启动时,控制台会打印HikariCP的连接池信息,比如“HikariPool-1 - Start completed.”。如果失败,优先看Caused by之后的内容,不要再翻前半部分堆栈了。

4.2 原生JDBC方式接入

在没有框架的老项目中,使用MySQL 8.0驱动连接数据库,逻辑依然清晰:

import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class JdbcTest { public static void main(String[] args) throws Exception { String url = "jdbc:mysql://127.0.0.1:3306/testdb" + "?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"; try (Connection conn = DriverManager.getConnection(url, "root", "123456"); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT VERSION() AS v")) { while (rs.next()) { System.out.println("MySQL Version: " + rs.getString("v")); } } } }

这段代码里的try-with-resources会在JDK 7及以上自动关闭连接、语句和结果集,避免资源泄漏。如果你还在用老式写法,请至少保证在finally中释放资源。运行之后如果控制台输出MySQL Version: 8.0.x,说明驱动Jar和连接配置都没问题。

4.3 验证驱动版本是否真的生效

很多问题出在“工程里有多个MySQL驱动Jar”,比如运行时实际用的是老驱动,你改造了半天也没用。可以用Java代码来快速确认当前实际加载的类:

System.out.println(Class.forName("com.mysql.cj.jdbc.Driver"));

或者更直接一点,在代码里打印驱动的版本信息:

java.sql.Driver driver = DriverManager.getDriver("jdbc:mysql://127.0.0.1:3306/testdb"); System.out.println(driver.getClass().getName());

如果你看到输出是com.mysql.cj.jdbc.Driver,就是新驱动。如果是com.mysql.jdbc.Driver,说明Jar没有替换干净。这个排查思路在遇到“明明改了pom却还是老行为”时非常有用。

5. 高频问题与排查技巧实录

5.1 问题速查表

我把最常见的问题和对策整理成一个表格,方便你遇到问题时直接对照:

现象根本原因解决方案
ClassNotFoundException: com.mysql.jdbc.Driver代码或配置仍使用旧类名改成com.mysql.cj.jdbc.Driver
Public Key Retrieval is not allowedMySQL 8.0默认认证插件是caching_sha2_password,且驱动未获准获取公钥URL加allowPublicKeyRetrieval=true
The server time zone value 'xxx' is unrecognized驱动无法解析数据库服务器时区URL加serverTimezone=Asia/Shanghai
Establishing SSL connection without server's identity verification is not recommended8.0驱动默认开启SSL,但未配置证书内网环境加useSSL=false;生产环境应配置证书
Cannot load driver class: com.mysql.cj.jdbc.Driver驱动Jar未正确引入或版本过旧确认Maven依赖存在,或手动引入Jar后重新构建
Access denied for user 'root'@'localhost'账号密码、主机授权问题检查MySQL用户表和host授权,确认密码正确

5.2 多个驱动Jar包冲突的处理

这是Java后端项目非常经典的坑。有些老项目在WEB-INF/lib下放了一个mysql-connector-java-5.1.x.jar,同时Maven又引入了8.x驱动,两个Jar都会注册java.sql.Driver,而你真正调用的时候可能由类加载顺序决定了使用哪个,行为难以预料。解决思路是:先通过前面提到的方式打印实际加载的Driver类名;如果发现是老驱动,优先把Maven依赖和lib目录中的老Jar统一成新版本,千万不要两个都保留。对于Tomcat等Web容器,还要特别注意lib目录和WEB-INF/lib的隔离关系,最稳妥的做法是只保留一处。

5.3 版本匹配速查:驱动支持哪些MySQL Server

关于驱动与Server版本的对应关系,我见过不少人把connector-j版本和mysql server 8.0强行划等号,认为只有版本号一致才能连。其实不是这样。官方支持的矩阵中,Connector/J 8.0.x既可以连接MySQL 5.7,也可以连接MySQL 8.0;Connector/J 8.1以上同样向后兼容老版本Server。反过来,老驱动5.1.x虽然连接MySQL 8.0通常也能跑,但身份认证、字符集、时区和性能方面都有隐患,能不用就不用。

我的建议是:驱动版本不低于8.0.28,优先用8.0.33或更高,连接MySQL 5.7/8.0都没问题。如果你的数据库是企业版或其他发行版,兼容性差距也不大,但升级驱动前后要做一次连接测试,这是最保险的做法。

5.4 我踩过的坑:连接串里藏着看不见的字符

有一次项目排查到半夜,MySQL连接时好时坏,最后发现URL里serverTimezone=Asia/Shanghai的等号附近混进了一个不可见字符,是复制文档时带进来的。这种问题特别难发现,因为你肉眼看不到。我养成了一个习惯:连接串一旦写好,先用文本编辑器的“显示所有字符”检查一遍,再去代码里粘贴。另外一个相关的坑是参数值里的&在XML配置中要写成&amp;,否则XML解析直接报错,Spring配置文件中尤其常见。

6. 关于驱动升级,最后再提几条实用建议

除了上面这些具体操作,我还想分享几个容易忽略的细节,这些都是在真实项目中积累出来的经验。

第一,驱动Jar包的版本号不要写动态版本,比如8.0.+。这种写法虽然本地构建方便,但可能某一天拉到一个不兼容的新版,导致生产环境行为突变。锁定具体版本号是最起码的习惯。

第二,如果使用的是Spring Boot,注意启动时如果看到Spring Boot 3.x的潜在版本冲突,请关注它默认依赖的驱动版本。Spring Boot 3.x基于Jakarta EE,数据库驱动本身的依赖变化不大,但如果你自定义了依赖版本,仍然要以“最终生效的那个版本”为准,而不是看pom.xml里声明了哪个。用mvn dependency:tree检查实际依赖是一个好习惯。

第三,对于大流量应用,我强烈建议开启批量重写参数:

rewriteBatchedStatements=true

这个参数会让addBatch方式的批量插入自动合并成多值insert,性能提升非常明显。再配合cachePrepStmts=true&useServerPrepStmts=true可以改善预编译语句的缓存效果。不过参数也不是越多越好,每加一个都要知道它解决什么问题,否则出了问题反而无从查起。

最后,如果你正在从旧驱动往MySQL 8.0驱动迁移,不要只改依赖不测功能。至少把启动、登录、列表查询、写操作这几条链路完整跑一遍,因为连接参数的变化可能影响到时间字段的读取方式、特殊字符的写入方式。一次升级看似简单,真正稳落地,靠的还是细心验证。

以上说的这些,都是我在实际项目中反复用过并且确认有效的做法。MySQL 8.0的JDBC驱动本身不复杂,但围绕Jar包版本、连接串参数和类加载机制展开的坑确实不少。你只要把这次提到的几个关键点记牢——类名用com.mysql.cj.jdbc.Driver,URL补全serverTimezone、useSSL、allowPublicKeyRetrieval,依赖坐标尽量用com.mysql:mysql-connector-j——大概率能避开九成以上的连接问题。如果还是遇到奇奇怪怪的报错,按照文中的排查表一步步查,总能在容器、依赖和连接串三个层面找到答案。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 6:13:44

把技能当项目经营:盘点、刻意练习与输出倒逼输入的完整方法论

“Skills”这个英文词&#xff0c;一度被我看成简历上的一栏。直到我把它当作一个独立项目来运营&#xff0c;才真正体会到&#xff1a;技能不是天赋的附属品&#xff0c;而是一套可以被盘点、拆解、训练、验证的资产组合。过去一年&#xff0c;我给自己定了一个代号叫“skills…

作者头像 李华
网站建设 2026/10/21 6:13:37

PostgreSQL数据类型全解析:类型转换、JSONB与性能优化

你是不是也遇到过这样的场景&#xff1a;两张表 JOIN 的时候&#xff0c;明明看着都是存手机号的字段&#xff0c;PG 却直接甩给你一句operator does not exist: text bigint&#xff1b;或者是金额字段用 FLOAT 存了两年&#xff0c;突然某一天对账对不上&#xff0c;差了那么…

作者头像 李华
网站建设 2026/10/21 6:12:40

模糊自整定增量式PID在STM32电机速度闭环中的工程实现

简介&#xff1a;一套基于STM32F103ZET6与编码器直流电机的模糊自整定增量式PID速度控制程序&#xff0c;面向嵌入式初学者、电机控制开发者及备赛学生。代码按照正点原子工程规范分块编写&#xff0c;注释清晰&#xff0c;相比普通增量式PID具备更强鲁棒性&#xff0c;可帮助读…

作者头像 李华
网站建设 2026/10/21 6:12:36

从爆单到叫停:AI眼镜的产品逻辑与供应链真相

最近智能硬件圈里讨论热度最高的&#xff0c;除了大模型落地&#xff0c;就是AI眼镜。尤其是某科技巨头旗下的AI眼镜&#xff0c;产品上市后订单量直接超出了预期&#xff0c;甚至到了“应接不暇”的地步。紧接着传来消息&#xff0c;原本计划中的国际市场扩张节奏要暂时放缓&a…

作者头像 李华
网站建设 2026/10/21 6:12:25

多智能体动态事件触发共识控制的Matlab仿真与实现

多智能体系统的分布式协同控制&#xff0c;这些年无论是在学术界还是工业界都是个大热点。以前我们做多机器人编队、无人机集群、卫星星座协同这类课题时&#xff0c;最头疼的问题之一就是&#xff1a;怎么用最少的信息交互&#xff0c;还能保证所有智能体最终达到一致的状态&a…

作者头像 李华
网站建设 2026/10/21 6:11:06

用Python与Pathlib打造可预览可回滚的命令行批量重命名工具

我在地铁上用手机整理素材库时&#xff0c;突然冒出一个想法&#xff1a;手头几千个杂乱的截图、文档和资源包&#xff0c;文件名要么是“IMG_2024xxxx”、“新建文档(5)”&#xff0c;要么是“最终版_v3_真最终版”&#xff0c;视觉上已经彻底失控。手动一个个改名根本不现实&…

作者头像 李华