作为一名长期使用IntelliJ IDEA进行Java开发的工程师,我经常遇到新手开发者在使用Spring Boot整合MyBatis时出现的数据库连接问题。最近团队里有个实习生就遇到了典型的"Failed to load driver class com.mysql.cj.jdbc.Driver"错误,这让我想起自己刚入门时踩过的那些坑。
这个错误通常会在你配置好application.properties文件,满怀期待地点击运行按钮时突然出现。控制台会显示类似这样的错误信息:
code复制Failed to load driver class com.mysql.cj.jdbc.Driver in either of HikariConfig class loader or Thread context classloader
我第一次遇到这个问题时也是一头雾水,后来才发现这其实是MyBatis和MySQL驱动版本不兼容的典型表现。就像组装电脑时CPU和主板不匹配一样,即使每个零件单独看都没问题,组合起来就是无法正常工作。
要解决这个问题,我们首先需要理解Spring Boot是如何加载数据库驱动的。当你使用Spring Boot的自动配置功能时,它会根据application.properties中的配置自动创建数据源。在这个过程中,HikariCP(Spring Boot默认使用的连接池)会尝试加载你指定的JDBC驱动类。
如果出现"Failed to load driver class"错误,本质上就是系统在类路径中找不到对应的驱动类。这就像你拿着钥匙去开车,却发现钥匙根本插不进锁孔——要么拿错了钥匙(驱动类不存在),要么锁芯换了(版本不兼容)。
根据我的经验,这个问题通常由以下几种情况引起:
完全缺失MySQL驱动依赖:项目pom.xml中根本没有声明mysql-connector-java依赖,就像没带钥匙就想开车门。
版本不匹配:这是最常见的情况。比如你使用的MyBatis-Spring-Boot-Starter版本需要MySQL 8.x的驱动,但你的pom.xml中却声明了5.x版本的MySQL驱动。
依赖冲突:项目中可能存在多个不同版本的MySQL驱动,Maven最终选择了不兼容的版本。就像同时带了好几把钥匙,结果拿错了。
配置错误:application.properties中的驱动类名拼写错误,或者使用了不匹配的驱动类名。
首先,确保你的application.properties配置正确。对于MySQL 8.x,配置应该类似这样:
code复制spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
注意几点:
在IntelliJ IDEA中,你可以很方便地查看项目的依赖树:
这会显示一个可视化的依赖关系图。重点关注mysql-connector-java,看看是否存在多个版本,或者版本是否被其他依赖覆盖。
你也可以在终端运行:
bash复制mvn dependency:tree
查找输出中的mysql-connector-java,确保它符合你的预期版本。
如果发现存在版本冲突,有几种解决方法:
直接声明版本:在pom.xml中明确指定mysql-connector-java的版本,并放在dependencies部分靠前的位置。
使用dependencyManagement:如果你使用的是多模块项目,可以在父pom中使用dependencyManagement统一管理版本。
排除冲突依赖:对于传递性引入的不兼容版本,可以使用exclusions标签排除。
例如:
xml复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</exclusion>
</exclusions>
</dependency>
根据我的项目经验,以下组合通常能很好地工作:
| MyBatis-Spring-Boot-Starter版本 | 推荐的MySQL驱动版本 |
|---|---|
| 2.2.x | 8.0.x |
| 2.1.x | 8.0.x |
| 1.3.x | 5.1.x |
对于大多数新项目,我建议使用以下配置:
xml复制<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
<scope>runtime</scope>
</dependency>
注意scope设置为runtime,因为通常我们只在运行时需要JDBC驱动。
IntelliJ IDEA的Maven Helper插件是排查依赖冲突的神器:
这个工具能直观地显示哪个依赖引入了冲突版本,大大节省排查时间。
有时候Maven依赖看起来没问题,但运行时还是找不到类。这时可以:
如果没有,说明驱动确实不在类路径中,需要检查打包配置。
Maven和IntelliJ IDEA有时会因为缓存表现出奇怪的行为。如果修改依赖后问题依旧,尝试:
最近帮助同事解决的一个典型问题:
解决方案是在根pom.xml的dependencyManagement中锁定版本:
xml复制<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
</dependencies>
</dependencyManagement>
然后在不兼容的模块中排除旧版本:
xml复制<dependency>
<groupId>com.old.module</groupId>
<artifactId>old-module-core</artifactId>
<exclusions>
<exclusion>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</exclusion>
</exclusions>
</dependency>
为了避免这类问题反复出现,我总结了几个最佳实践:
保持依赖更新:定期检查依赖版本,特别是Spring Boot和MyBatis的版本兼容性矩阵。
使用BOM管理版本:Spring Boot提供了dependencyManagement,可以简化版本管理:
xml复制<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.6.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
java复制@SpringBootTest
class DatabaseConnectionTest {
@Autowired
private DataSource dataSource;
@Test
void testConnection() throws SQLException {
try (Connection connection = dataSource.getConnection()) {
assertTrue(connection.isValid(1000));
}
}
}