最后更新:2026-08-20
适用场景:Spring Boot 连接 MySQL、spring.datasource、MySQL 驱动、JDBC URL、数据库连接失败、Communications link failure、Access denied for user

Spring Boot 连接 MySQL 本身不复杂,真正容易出问题的是这些地方:驱动依赖没加、JDBC URL 写错、账号密码不对、数据库没开放远程访问、服务器防火墙没放行、配置被 profile 覆盖了。

很多人看到启动报错,会先去改 Controller 或 Mapper。其实大多数连接 MySQL 的问题,应该先看配置和网络。

这篇文章按一个普通 Spring Boot 项目来写,从依赖、配置、建库、启动验证到常见报错排查,照着做基本就能定位问题。

一、先看结论

Spring Boot 连接 MySQL,最少需要三件事:

1. 项目里有 MySQL 驱动依赖
2. application.yml 里配置 spring.datasource
3. MySQL 数据库能被当前应用访问

Maven 依赖一般这样写:

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

application.yml 最基础配置:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

如果你只是连接数据库,不一定非要先引入 MyBatis 或 JPA。MySQL 驱动和 spring.datasource 是基础,MyBatis、JPA、JdbcTemplate 都是在这个基础上继续访问数据。

二、先准备一个 MySQL 数据库

先确认 MySQL 本身能用。

本地 MySQL 可以用命令行测试:

mysql -uroot -p

登录后创建一个测试库:

CREATE DATABASE demo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

如果你的 MySQL 版本不支持 utf8mb4_0900_ai_ci,可以换成更通用的:

CREATE DATABASE demo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

开发环境为了省事,很多人直接用 root。本地临时测试可以,但生产环境不建议应用直接连 root。

更推荐创建一个业务用户:

CREATE USER 'demo_user'@'%' IDENTIFIED BY 'demo_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON demo.* TO 'demo_user'@'%';
FLUSH PRIVILEGES;

如果只是本机连接,可以把 % 换成 localhost

CREATE USER 'demo_user'@'localhost' IDENTIFIED BY 'demo_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON demo.* TO 'demo_user'@'localhost';
FLUSH PRIVILEGES;

不要一上来就给应用账号 ALL PRIVILEGES。开发环境问题不大,生产环境最好只给应用需要的权限。

三、添加 MySQL 驱动依赖

Spring Boot 项目使用 Maven,可以在 pom.xml 里加:

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

如果你使用 Gradle:

runtimeOnly 'com.mysql:mysql-connector-j'

注意现在推荐的 Maven 坐标是:

com.mysql:mysql-connector-j

以前经常看到这种老写法:

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

新项目不建议继续用老坐标。MySQL Connector/J 从 8.0.31 开始已经切到 com.mysql:mysql-connector-j 这组坐标。

如果你用的是 Spring Boot 官方依赖管理,一般不要自己手动写 MySQL 驱动版本号,让 Spring Boot 管就行。除非你非常明确要覆盖版本,否则自己指定版本反而容易引入兼容问题。

如果 Maven 依赖下载失败,可以先看:Maven 国内镜像配置教程

四、application.yml 配置 MySQL

最常见写法:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: demo_user
    password: demo_password
    driver-class-name: com.mysql.cj.jdbc.Driver

这几个配置分别是什么意思:

url:数据库连接地址
username:数据库用户名
password:数据库密码
driver-class-name:MySQL JDBC 驱动类

driver-class-name 有时可以不写,Spring Boot 能根据 JDBC URL 推断出来。但新手项目里建议先写上,排查时更直观。

如果你上一篇已经看过配置文件,可以继续按多环境方式拆:

src/main/resources/
├── application.yml
├── application-dev.yml
└── application-prod.yml

通用配置写到 application.yml

spring:
  application:
    name: demo-api

本地数据库配置写到 application-dev.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo_dev?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

生产数据库配置写到 application-prod.yml

spring:
  datasource:
    url: jdbc:mysql://mysql-prod:3306/demo_prod?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: demo_user
    password: ${DB_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver

生产密码不要写死,建议用环境变量:

password: ${DB_PASSWORD}

启动时指定环境:

java -jar demo-api.jar --spring.profiles.active=prod

配置文件基础可以看:Spring Boot 配置文件怎么写

五、JDBC URL 怎么写

MySQL 的 JDBC URL 基本格式是:

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

本地数据库:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai

远程数据库:

spring:
  datasource:
    url: jdbc:mysql://192.168.1.100:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai

Docker Compose 里连接同一个网络下的 MySQL 服务:

spring:
  datasource:
    url: jdbc:mysql://mysql:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai

这里的 mysql 通常是 docker-compose.yml 里的服务名:

services:
  mysql:
    image: mysql:8.4
    environment:
      MYSQL_DATABASE: demo
      MYSQL_USER: demo_user
      MYSQL_PASSWORD: demo_password
      MYSQL_ROOT_PASSWORD: root_password
    ports:
      - "3306:3306"

  demo-api:
    image: demo-api:latest
    environment:
      SPRING_PROFILES_ACTIVE: prod
      DB_PASSWORD: demo_password

注意:应用在宿主机跑,连接 Docker 里的 MySQL,一般用 localhost:3306。应用和 MySQL 都在 Docker Compose 同一个网络里,应用连接 MySQL 服务名,比如 mysql:3306

这两个场景不要混。

六、用 JdbcTemplate 测一下是否连通

如果只是验证 MySQL 是否连通,可以先不用写完整业务。

加一个测试接口:

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DbTestController {

    private final JdbcTemplate jdbcTemplate;

    public DbTestController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @GetMapping("/db/ping")
    public String ping() {
        Integer result = jdbcTemplate.queryForObject("select 1", Integer.class);
        return "mysql ok: " + result;
    }
}

访问:

http://localhost:8080/db/ping

如果返回:

mysql ok: 1

说明 Spring Boot 到 MySQL 的基本连接已经通了。

这里有个前提:项目里需要有 JDBC 相关 starter。比如:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

如果你用 MyBatis Starter 或 Spring Data JPA,它们通常也会带上相关能力。不同项目依赖组合不同,排查时可以看 Maven 依赖树。

mvn dependency:tree

七、如果使用 MyBatis

如果你的项目准备使用 MyBatis,除了 MySQL 驱动,还需要 MyBatis 相关依赖。

常见写法类似:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>3.0.4</version>
</dependency>

然后配置 Mapper XML 路径:

mybatis:
  mapper-locations: classpath*:mapper/**/*.xml
  type-aliases-package: com.example.demo.entity

Mapper 接口可以这样:

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface UserMapper {

    @Select("select count(*) from user")
    int countUsers();
}

这里要分清楚两个问题:

Spring Boot 连不上 MySQL:先查 spring.datasource、驱动、网络、账号密码
MyBatis 找不到 SQL:再查 Mapper 扫描、XML 路径、namespace、方法名

如果报的是 Invalid bound statement,重点就不是 MySQL 连接,而是 MyBatis 映射关系。

可以继续看:MyBatis Invalid bound statement 怎么处理

八、如果使用 JPA

如果你用 Spring Data JPA,依赖通常是:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

再配 MySQL 驱动:

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

开发环境可以临时这样配置:

spring:
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

但生产环境不要随便用 ddl-auto: update

更建议生产环境:

spring:
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false

表结构变更用 Flyway、Liquibase 或人工审核后的 SQL 脚本,不要让应用启动时自动改生产库表结构。

九、常见报错怎么排查

1. Failed to configure a DataSource

这个报错通常说明 Spring Boot 想配置数据源,但缺少关键信息。

重点查:

1. 是否配置了 spring.datasource.url
2. 是否添加了 MySQL 驱动依赖
3. 配置文件是否真的生效
4. active profile 是否正确

详细排查可以看:Spring Boot DataSource 报错怎么处理

这个一般是网络没通。

先在应用所在机器上测试:

telnet 192.168.1.100 3306

或者:

nc -vz 192.168.1.100 3306

如果连不上,先不要改 Java 代码,去查:

MySQL 是否启动
MySQL 是否监听 3306
服务器防火墙是否放行
云服务器安全组是否放行
MySQL bind-address 是否限制了地址
Docker 端口是否映射

3. Access denied for user

这个一般是账号、密码、权限或 host 不匹配。

比如你创建的是:

CREATE USER 'demo_user'@'localhost' IDENTIFIED BY 'demo_password';

但应用从另一台机器连接,就可能没有权限。远程连接需要对应的 host 授权,比如:

CREATE USER 'demo_user'@'%' IDENTIFIED BY 'demo_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON demo.* TO 'demo_user'@'%';
FLUSH PRIVILEGES;

生产环境可以把 % 收窄成具体服务器 IP,不要为了省事长期开放给所有来源。

4. Unknown database

说明数据库名不存在,或者 URL 里的库名写错了。

登录 MySQL 看一下:

SHOW DATABASES;

如果没有,就创建:

CREATE DATABASE demo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

5. Public Key Retrieval is not allowed

有些 MySQL 8 连接场景会遇到这个报错。

开发环境可以临时在 URL 后面加:

allowPublicKeyRetrieval=true

例如:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true

但生产环境不要只为了消除报错就随便关闭安全校验。更稳的做法是确认账号认证方式、SSL 配置和连接来源。

6. The server time zone value is unrecognized

这类时区问题可以先在 JDBC URL 里指定:

serverTimezone=Asia/Shanghai

完整示例:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai

同时也建议检查 MySQL 服务器时区,不要只靠应用端兜底。

常见坑

第一个坑:只看代码,不看数据库是否能连。

连接 MySQL 失败时,先在应用服务器上用 mysqltelnetnc 测一下。网络不通时,Java 代码写得再对也没用。

第二个坑:本地和 Docker 场景混在一起。

宿主机访问 Docker MySQL 用 localhost:3306,容器内访问同网络 MySQL 用服务名,比如 mysql:3306。很多连接失败就是这个地址写反了。

第三个坑:生产环境用 root 账号。

应用账号应该只给业务库需要的权限,不要直接 root 连接生产库。

第四个坑:把数据库密码提交到仓库。

本地开发可以写在 application-dev.yml,生产环境建议用环境变量、外部配置或平台密钥管理。

第五个坑:依赖版本自己乱指定。

Spring Boot 已经做了依赖版本管理,普通项目不要手动给每个依赖写版本。特别是 MySQL 驱动、MyBatis Starter、Spring Boot 版本之间,乱配版本会带来额外问题。

排查清单

Spring Boot 连接 MySQL 失败时,按这个顺序查:

1. MySQL 服务是否启动
2. 数据库名是否存在
3. 应用所在机器是否能访问 MySQL 的 IP 和端口
4. 云服务器安全组和防火墙是否放行 3306
5. MySQL 用户名和密码是否正确
6. MySQL 用户 host 是否允许当前来源连接
7. pom.xml 是否有 mysql-connector-j
8. spring.datasource.url 是否写对
9. application.yml / application-prod.yml 是否真的生效
10. spring.profiles.active 是否是预期环境
11. Docker 场景下连接地址是否写成了正确服务名
12. 是否被环境变量或启动参数覆盖
13. 报错是 DataSource 连接问题,还是 MyBatis XML 映射问题

常见问题 FAQ

1. Spring Boot 连接 MySQL 必须写 driver-class-name 吗?

不一定。

Spring Boot 通常能根据 jdbc:mysql:// 推断出驱动类。但新手项目里可以先写:

driver-class-name: com.mysql.cj.jdbc.Driver

排查时更直观。

2. mysql-connector-java 和 mysql-connector-j 用哪个?

新项目用:

<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>

老的 mysql:mysql-connector-java 不建议新项目继续使用。

3. MySQL 驱动要不要写 version?

如果项目使用 Spring Boot 的依赖管理,通常不要写。

让 Spring Boot 管理版本更省心。只有在明确知道自己要覆盖版本时,再单独指定。

4. application.yml 配了 datasource,为什么还是没生效?

先查 profile。

比如你启动时指定了:

--spring.profiles.active=prod

那最终可能是 application-prod.yml 覆盖了默认配置。

也要看环境变量和启动参数有没有覆盖。

5. Spring Boot 连接 Docker 里的 MySQL,host 写什么?

看应用跑在哪里。

如果 Spring Boot 跑在宿主机,MySQL 容器映射了 3306:3306,一般写:

localhost:3306

如果 Spring Boot 也在 Docker Compose 里,并且和 MySQL 在同一个网络,通常写 MySQL 服务名:

mysql:3306

6. 生产环境可以用 ddl-auto=update 吗?

不建议。

开发环境可以临时用,生产环境最好用 validate,表结构变更交给 Flyway、Liquibase 或审核后的 SQL 脚本。

不一定。

它只说明应用到 MySQL 的连接没建立成功。可能是 MySQL 没启动,也可能是 IP、端口、防火墙、安全组、Docker 网络、MySQL 监听地址的问题。

最后总结

Spring Boot 连接 MySQL,核心不是背配置项,而是按顺序排查:

先确认 MySQL 能访问
再确认驱动依赖存在
再确认 spring.datasource 生效
最后再看 MyBatis / JPA / 业务代码

如果连接都没通,不要急着改 Mapper、Entity 或 Controller。

先把 jdbc:mysql://...、账号密码、网络、profile 查清楚,问题通常就能定位到。

相关文章

Spring Boot 教程

Spring Boot 配置文件怎么写

Spring Boot DataSource 报错怎么处理

MyBatis Invalid bound statement 怎么处理

Maven 国内镜像配置教程

Spring Boot JDK 兼容表

参考资料

Spring Boot 官方文档:SQL Databases

Spring 官方指南:Accessing data with MySQL

MySQL Connector/J Developer Guide

MySQL Connector/J Maven 坐标变更说明

更新记录

2026-08-20:
- 创建文章《Spring Boot 连接 MySQL》
- 增加 MySQL 驱动依赖、application.yml、JDBC URL 示例
- 增加本地、远程、Docker Compose 连接场景
- 增加 JdbcTemplate 连通性测试示例
- 增加 MyBatis、JPA 使用场景说明
- 增加常见报错和排查清单