ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

MySQL驱动Maven坐标变更:从mysql-connector-java到mysql-connector-j的迁移指南

2026/10/6 13:18:57 拓冰建站 浏览量
MySQL驱动Maven坐标变更:从mysql-connector-java到mysql-connector-j的迁移指南 先说一个大部分人都踩过或即将踩的坑去 Maven 中央仓库搜 MySQL 驱动搜出来两个完全不同的坐标旧的是mysql:mysql-connector-java新的是com.mysql:mysql-connector-j。名字里带 java 的反而更老只有一个 j 的才是目前官方主推的。这两个坐标指向的其实是同一个东西——MySQL 官方的 JDBC 驱动 Connector/J也就是 Java 语言连接 MySQL 用的那个驱动包。这个改名是从 8.0.31 版本正式开始的。在那之前所有教程、博客、Spring Boot 项目里写的都是mysql:mysql-connector-java突然官方宣布切换坐标网上资料一混就很容易让人困惑是不是换了驱动是不是要改代码两个能不能混用这篇文章就是来把这件事讲透的。适合刚接触 Java 项目、连 MySQL 时总报错的新人也适合正在升级 Spring Boot 或连接池版本、需要确认依赖坐标的老项目维护者更欢迎那些只想搞清楚 Maven 坐标为什么长得不一样的人一起看。1. 先搞清楚一个驱动两个名字1.1 新旧坐标对比先看这张表先把最核心的信息摆出来。四个坐标信息一变其他基本没动维度旧坐标新坐标groupIdmysqlcom.mysqlartifactIdmysql-connector-javamysql-connector-j常见版本段5.1.x、8.0.11 ~ 8.0.308.0.31 之后所有版本、9.x官方产品名MySQL Connector/JMySQL Connector/J驱动主类com.mysql.cj.jdbc.Drivercom.mysql.cj.jdbc.Driver包名结构com.mysql.cj.*com.mysql.cj.*JDBC 连接串格式jdbc:mysql://...jdbc:mysql://...从 8.0.31 开始官方发布说明里就明确写了坐标切换后续的 9.x 系列发布时已经没有旧坐标的版本了。你可能在网上或者某些老项目的 pom 里见过旧坐标下挂着 8.0.33 这种靠后的版本号那属于过渡期的兼容性同步发布别把这个当成“旧坐标还能继续用”的理由。对于新项目我建议一律使用com.mysql:mysql-connector-j这是最干净的做法。1.2 构件名、驱动类名、包名是三回事平时讨论里这三样东西经常被混在一起这是很多人搞不清新旧坐标的根源。第一jar 内部的包名一直是com.mysql.cj.*不管是旧坐标还是新坐标这点从来没变过。第二8.x 时代的驱动主类一直是com.mysql.cj.jdbc.Driver坐标改了它也没改。第三真正容易造成记忆错乱的是 5.x 时代的驱动类叫com.mysql.jdbc.Driver少了个 cj。于是很多人的脑子里堆了三组相似但不相同的名字换版本的时候经常把坐标和类名一起换错。判断新旧最可靠的依据就是 Maven 坐标本身groupId 是mysql还是com.mysqlartifactId 是mysql-connector-java还是mysql-connector-j。别的都不用看先看坐标就对了。2. 为什么官方要折腾这次改名2.1 旧坐标和官方产品名长期对不上MySQL 官方文档里这个 Java 连接器的名字一直叫 Connector/J从来没叫过 “mysql-connector-java”。但 Maven 坐标偏偏用了mysql-connector-java这就导致一个很分裂的局面你在官方文档、错误提示、连接串注释里看到的是 Connector/J去 Maven 仓库搜的时候却在搜 mysql-connector-java。尤其是搜出来的结果还可能混着 5.x 的老教程信息根本对不上。另外MySQL 家其他语言的连接器命名是成体系的.NET 的叫 Connector/NETPython 的叫 Connector/PythonNode.js 的叫 Connector/Node.js都带着官方产品名前缀唯独 Java 的在 Maven 里是个单独的 --java。这次改名之后artifactId 直接叫mysql-connector-j和官方产品名对齐了一眼就能认出这是官方连接器搜索引擎和 IDE 也少了很多歧义。2.2 顺着 Maven 规范把 groupId 也修了Maven 仓库的 groupId 惯例是使用反域名比如com.fasterxml.jackson、org.springframework、com.google.code.gson这是为了在全局范围内保证唯一性。旧的mysql这种裸 groupId 虽然短但在大型组织内部的私有仓库里很容易和某些内部模块撞名或者被其他依赖意外传递进来造成混乱。改成com.mysql之后和官方域名一致坐标的归属一目了然也符合 Maven 生态里“用域名倒序标识组织”的约定。这次改坐标其实是把两个不规范一次解决了artifactId 对齐产品名groupId 对齐域名规范。2.3 新坐标背后其实是 JAR 结构升级坐标切换不是单纯改个名字8.0.31 版本的驱动在打包方式上也升级成了 multi-release JAR。什么意思就是一个 jar 文件里可以按 JDK 版本放多套实现低版本 JDK 会自动用兼容的部分高版本 JDK 可以用上新 API。这样官方就能在保持“最低支持 JDK 8”的同时让新版本 JDK 用户享受更优的实现。更实际的影响是在 Java 模块系统下。如果项目走 jlink 或者模块化新 jar 的 manifest 里声明了明确的自动模块名com.mysql.cj引入依赖时模块名是可预期的。而旧 jar 因为没有明确声明模块名往往只能按文件名推导得到类似mysql.connector.java的结果对模块化项目来说非常难受。顺手解决了这个问题也是官方坚持在 8.0.31 节点切换的原因之一。按我实际处理过的情况看这次改名不是换了引擎驱动内部的协议实现、行为特性、异常体系全都延续下来了变的只是“外壳”。所以项目里遇到这个坐标切换完全不用担心功能差异。3. 实操迁移从旧坐标换到新坐标3.1 Maven 项目怎么改Maven 的改法最直接把 dependency 块整体换掉。改之前是dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.30/version /dependency改之后是dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId version8.0.33/version /dependency版本号我建议挑一个当前比较稳定的 8.0.x 或 9.x 版本具体数值去 Maven 中央仓库看最新发布即可。如果你的项目里有 dependencyManagement 统管版本那就更简单了把版本号抽成一个 property只改一处properties mysql.version8.0.33/mysql.version /properties dependencyManagement dependencies dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId version${mysql.version}/version /dependency /dependencies /dependencyManagement这样做的好处是后续升级驱动时不用翻遍所有 module。我见过不少多模块项目依赖散落各处升级时漏改了一个地方结果线上还在用旧驱动排查起来相当麻烦。3.2 Gradle 项目怎么改Gradle 的写法更短改之前是implementation mysql:mysql-connector-java:8.0.30改之后是implementation com.mysql:mysql-connector-j:8.0.33老项目里如果还用 Groovy DSL注意字符串里的坐标别拼错。Kotlin DSL 写法一样就是字符串换成双引号。Gradle 对坐标匹配更严格group 和 artifact 对不上会直接提示找不到依赖所以这种迁移在 Gradle 项目里反而不容易悄悄失败。3.3 连接代码和配置几乎不用动这是很多人最关心的问题改了坐标代码要动吗答案是不用。JDBC 连接串格式不变还是jdbc:mysql://127.0.0.1:3306/demo?useSSLfalseserverTimezoneAsia/Shanghai。驱动类名不变如果你在配置文件里显式写了driver-class-name用的还是com.mysql.cj.jdbc.Driver。Spring Boot、HikariCP、Druid 这些连接池配置也都原样保留。举一个 Spring Boot 里的常见配置坐标换了之后这部分一字不改spring.datasource.urljdbc:mysql://127.0.0.1:3306/demo?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai spring.datasource.usernameroot spring.datasource.password123456 spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver如果你以前用的是Class.forName(com.mysql.cj.jdbc.Driver)这种写法同样不用改。唯一要记住的是5.x 时代的com.mysql.jdbc.Driver已经废弃如果项目里写的是这个说明升级 MySQL 8 驱动那一步就没走完这次正好一起改掉。3.4 检查还有谁在带旧坐标单模块项目改完就完了但多模块项目或者接入了第三方 starter 的项目很可能存在某个间接依赖悄悄把旧坐标带进来。我建议改完后跑一次依赖树检查。Maven 下执行mvn dependency:tree -Dincludesmysql:*Gradle 下执行./gradlew dependencies --configuration runtimeClasspath | grep mysql如果发现有旧坐标残留优先在 dependencyManagement 里统一锁定新坐标版本实在处理不掉可以在引入该 starter 的责任链上排除旧坐标exclusions exclusion groupIdmysql/groupId artifactIdmysql-connector-java/artifactId /exclusion /exclusionsGradle 里的排除写法是implementation(com.example:some-starter:1.0.0) { exclude group: mysql, module: mysql-connector-java }另外有一个很容易被忽略的点新 jar 的文件名变成了mysql-connector-j-8.0.33.jar和旧的mysql-connector-java-8.0.30.jar不一样。如果你们的构建脚本、监控探活或者打包配置里有按文件名过滤 mysql-connector-java 的逻辑记得同步改否则会有部署物料漏包的风险。4. 常见问题与排查实录4.1 新旧坐标同时出现在 classpath 里这是我见过最多的情况。表现是项目还能启动但偶尔报一些莫名其妙的NoSuchMethodError、AbstractMethodError或者日志里一会儿说加载了旧驱动一会儿又说加载了新驱动。用依赖树一查发现旧坐标和新坐标同时存在版本还不一致。原因多半是项目自己改了新坐标但某个第三方 starter 或者某个遗留 module 还声明着旧坐标两边都进了最终 classpath。JVM 加载类时按 classpath 顺序来谁在前面谁生效结果就是行为不可控。解决办法是先跑一遍mvn dependency:tree看全貌再按 3.4 的方式排除旧坐标或统一版本。这里我强烈建议用 dependencyManagement 锁版本比到处写排除规则省心得多。4.2 驱动加载报错No suitable driver 的排查顺序“No suitable driver found for jdbc:mysql://...” 是经典报错新手遇到容易慌老项目升级时遇到也不少。我的排查顺序是这样的第一确认依赖真的被编译进去了用依赖树看一眼排除掉 scope 误设、optional 误标的情况。第二确认连接串前缀没写错MySQL 必须是jdbc:mysql://少写个 s 或者写成jdbc:mysql: //都是白忙。第三确认 driver-class-name 没写旧值com.mysql.jdbc.Driver特别是从 5.x 升级上来的项目。最直接的自检方法写一个两行的小 main 方法验证驱动类能被加载public class CheckDriver { public static void main(String[] args) throws Exception { Class.forName(com.mysql.cj.jdbc.Driver); System.out.println(driver loaded); } }如果这段能跑通问题基本就在配置层继续查 URL 和连接池配置如果这里就抛ClassNotFoundException那说明依赖确实没进来回第一步查坐标。4.3 Spring Boot 大版本升级引发的坐标错位Spring Boot 自己管理了很多依赖版本MySQL 驱动也在名单里。Spring Boot 2.7 这条线默认管理的还是mysql:mysql-connector-java到了 Spring Boot 3.x依赖管理切换成了com.mysql:mysql-connector-j。如果你在做 2.x 到 3.x 的升级项目里手动写了旧坐标并指定了版本就可能出现 Spring Boot 想管新坐标、你用手动旧坐标覆盖的情况两边打架的现场很容易复现。我处理这类升级时的习惯是先把项目里所有mysql-connector-java全局搜索一遍全部替换成mysql-connector-j然后删掉手动指定的旧版本号让 Spring Boot 的 BOM 统一接管。如果公司规范要求显式写版本就提取到 properties 里锁成一个值保证全局只有一个版本来源。4.4 冷门但真实的坑按文件名扫描 jar 的逻辑这个坑大部分人遇不到但遇到了就很头疼。有些项目的打包插件、监控脚本、安全扫描工具会按 jar 文件名做过滤比如“找出所有包含 mysql 的 jar 然后统一处理”。旧坐标下文件名是mysql-connector-java-8.0.30.jar新坐标下变成mysql-connector-j-8.0.33.jar过滤规则如果写的是完整旧文件名新驱动就漏了。另外如果你的安全扫描工具依赖已知漏洞库库里记录的坐标还是旧格式扫描结果可能对新坐标不识别。这种时候不用慌更新一下规则库或者把依赖坐标在文档里备注清楚就行。我遇到过 CI 脚本里写死了旧 jar 名做拷贝迁移后打包一直失败查了半天才发现是文件名匹配的问题这种细节真的容易漏。下面把几种常见现象和解决方法收成一张速查表现象原因处理方式启动日志同时出现新旧驱动多个依赖各带各的坐标dependency:tree 定位来源排除旧坐标或用 BOM 锁版本No suitable driver 报错坐标没进来、URL 写错、驱动类写错按 4.2 顺序逐项排查升级 Spring Boot 后启动异常手动旧坐标覆盖了 BOM 的新坐标全局替换坐标让 BOM 统一管理构建脚本找不到 jar文件名从 mysql-connector-java 变了同步更新按文件名过滤或复制的逻辑5. 写在最后一点个人体会我自己的习惯是不管项目在哪个 Spring Boot 版本上pom 或 build.gradle 里的 MySQL 驱动坐标永远显式写死不让 BOM 去猜。新项目直接上com.mysql:mysql-connector-j老项目只要代码里用的驱动类是com.mysql.cj.jdbc.Driver改坐标就是唯一要做的事。踩过几次新旧坐标共存的坑之后我每次动依赖之前都先跑一遍 dependency:tree这个习惯帮我省了不少排查时间。最后再分享一个小技巧改完坐标别急着启动先看一眼依赖树里 mysql 相关的内容确认只有一个坐标、一个版本。这一眼花不了十秒钟但能避免后面几小时的排障。驱动这件事本身不难难的是名字和版本太多容易自我怀疑看到坐标规整了心里就有底了。