尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

SpringBoot+JDBC连接MySQL完整配置与避坑指南

发布时间:2026/9/29 17:19:12

资讯中心
01
ARTICLE

SpringBoot+JDBC连接MySQL完整配置与避坑指南

SpringBoot+JDBC连接MySQL完整配置与避坑指南
简介这是一份围绕Java SpringBoot整合JDBC连接MySQL数据库的完整解决方案目标读者是Java后端初学者、正在做课程设计或毕业设计的在校生以及需要在业务项目中快速接入数据库的开发者。压缩包共136个文件总体积637.42MB包含.java源码与.class编译产物、.sql数据库脚本、.xml与.properties配置文件以及dll、exe、msi、zip等运行时依赖和安装工具。其中sql脚本可直接导入数据库快速生成表结构和演示数据dll与exe多对应MySQL驱动或系统组件msi与zip提供不同环境下的安装与免安装选项便于减少本地环境配置的障碍。资源以Jdbcdemo工程为主体涵盖用户实体、JDBC控制器、SpringBoot启动类等关键代码覆盖从数据源配置、SQL执行到结果返回的完整链路目录结构也按功能模块拆分便于读者对照学习。目前已有598人学习下载适合希望利用一套真实工程系统掌握SpringBoot使用JDBC连接MySQL的中初级开发者。1. SpringBoot JDBC 连接 MySQL能落到工程里的那套配置开发中把 JDBC 和 SpringBoot 接到一起本身不算什么新东西可真到动手时大多数人卡住的位置往往出人意料不是 SQL 写不对而是驱动版本和 MySQL 服务端不匹配、SSL 连接报错、连接池默认参数撑不住业务压力。这套解决方案把「SpringBoot 项目通过 JDBC 连接 MySQL」的完整链路整理好了从 mysql-connector-j 驱动的选型、application.properties 里的数据源配置到 JdbcTemplate 封装后的增删改查、事务边界控制再到连接池参数怎么调均包含在源码包和安装包里。适合两种人一种是刚接触 SpringBoot 想用最朴素方式把 MySQL 跑通的新手另一种是接手旧项目被数据库连接报错和诡异超时反复折腾的开发者。拿到手之后按下面的步骤配置基本可以绕开我当年踩过的那些坑。2. SpringBoot JDBC 连 MySQL环境准备与选型思路在写任何代码之前先把环境理清楚能省去后面一半的排错时间。这个环节容易翻车的地方主要有三个MySQL 服务端版本、JDBC 驱动版本、SpringBoot 版本。三者并不是随便组合都能正常工作版本不匹配时驱动的加载机制会发生改变常见的报错是java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed或者The server time zone value Öйú±ê׼ʱ¼ä is unrecognized。2.1 安装包与版本搭配先定 MySQL 再定驱动我一般先装 MySQL 再选驱动。这套方案自带的安装包是社区版安装时注意两点一是端口默认 3306避免和本机已有的 MySQL 实例冲突二是 root 密码要设置一个自己能记住的后面连接测试全靠它。装好之后用命令行验证一下服务是否在监听。# 检查 MySQL 服务状态Windows 用 net start | findstr mysqlLinux 用 systemctl netstat -an | grep 3306 # 结果里出现 0.0.0.0:3306 LISTENING 或 :::3306 LISTEN 说明服务正常驱动方面现在统一使用mysql-connector-jgroupId 是com.mysqlartifactId 是mysql-connector-j。它替代了老式的mysql-connector-java两者的包名区别很小但坐标不同。对于 SpringBoot 2.7.x 推荐 8.0.x 系列驱动对于 SpringBoot 3.x 则需要 8.0.31 以上或新增的 9.x 驱动。这个对应关系非常关键驱动版本过低在 JDK 17 上直接加载失败报UnsupportedClassVersionError。2.2 依赖引入只需要一个 starter 和一条驱动依赖SpringBoot 工程里使用 JDBC 其实不需要配置数据源池只引入spring-boot-starter-jdbc就够了。它会自动把DataSource和JdbcTemplate装配好但注意默认的连接池是 HikariCP这是 SpringBoot 官方默认选择也是性能测试里表现最好的一个。如果你的项目里看到用的是 DBCP 或 C3P0那就是有人手动排除掉 HikariCP 换的建议换回来。!-- pom.xml 里核心依赖 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jdbc/artifactId /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency这段配置里scoperuntime的意思是编译期不需要驱动类运行时由 SpringBoot 自动加载。要注意如果你的项目里手动使用Class.forName(com.mysql.cj.jdbc.Driver)那么在编译期就需要这个依赖scope 要改成compile或者去掉 runtime 限定。我遇到过一种情况是有人把驱动手动放在 Tomcat 的 lib 目录里导致和项目内 Maven 依赖重复加载出现Unable to load authentication plugin caching_sha2_password的报错这种情况把外部 lib 里的驱动删掉即可。2.3 初始化数据库建库建表脚本源码包里附带了一份init.sql里边把演示用的用户表、订单表结构和测试数据都准备好了。手动执行一遍的过程最好是在命令行里完成因为你会直观地看到编码和字符集设置。mysql -u root -p init.sql # 提示输入密码后执行脚本里包含 CREATE DATABASE demo_db DEFAULT CHARACTER SET utf8mb4;utf8mb4这个字符集很重要。MySQL 8.0 默认字符集是utf8mb4它才能完整存储四字节的 emoji 和生僻汉字。如果你的表用的是老旧的utf8遇到特殊字符就会变成???排查起来非常头疼。建表之后用SHOW CREATE TABLE user;看一眼实际生效的字符集确认无误再进下一步。3. SpringBoot JDBC数据源配置与增删改查落地现在进入正题把 SpringBoot 项目里的数据源配置好然后用 JdbcTemplate 写一套完整的增删改查。JdbcTemplate 是 Spring 对 JDBC 的封装它把连接获取、PreparedStatement 创建、结果集映射这些样板代码都处理掉了但依然保留 SQL 的直接控制权不像 MyBatis 或 JPA 那样引入额外的映射层。用 JDBC 的场景追求的就是对 SQL 的绝对控制。3.1 application.properties 数据源参数SpringBoot 的自动配置会读取spring.datasource前缀下的属性来创建数据源。下面这套配置是经过实践验证的可以直接复制使用。# 完整的数据源配置注意 url 中参数的含义 spring.datasource.urljdbc:mysql://localhost:3306/demo_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue spring.datasource.usernameroot spring.datasource.password你的密码 spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver # HikariCP 连接池参数 spring.datasource.hikari.minimum-idle5 spring.datasource.hikari.maximum-pool-size20 spring.datasource.hikari.connection-timeout30000 spring.datasource.hikari.idle-timeout600000URL 里的参数逐个说useUnicodetruecharacterEncodingutf8确保中文以 UTF-8 传输。serverTimezoneAsia/Shanghai避免 MySQL 8.0 服务器时区和 JVM 时区不一致导致的The server time zone value异常。useSSLfalse本地开发环境无 SSL 证书时关闭加密连接若为 true 且 MySQL 未开启 SSL 会直接报错。allowPublicKeyRetrievaltrueMySQL 8.0 使用 caching_sha2_password 认证时如果客户端第一次连接需要从服务器获取公钥这个参数必须为 true否则报Public Key Retrieval is not allowed。连接池参数里maximum-pool-size不是越大越好。MySQL 默认最大连接数是 151如果多个应用实例共享同一个 MySQL每个实例都设置过大会把连接数打满。一般单实例的 web 应用20 到 50 足够用。3.2 使用 JdbcTemplate 操作数据库配置完成之后JdbcTemplate 会被 SpringBoot 自动注入到任何需要的地方。我写的增删改查示范不搞复杂的封装直接用最直观的 JdbcTemplate API 演示。Repository public class UserRepository { private final JdbcTemplate jdbcTemplate; public UserRepository(JdbcTemplate jdbcTemplate) { this.jdbcTemplate jdbcTemplate; } // 查询单条记录注意 RowMapper 的使用方式 public User findById(Long id) { String sql SELECT id, name, email FROM user WHERE id ?; return jdbcTemplate.queryForObject(sql, (rs, rowNum) - new User( rs.getLong(id), rs.getString(name), rs.getString(email) ), id); } // 查询列表 public ListUser findAll() { String sql SELECT id, name, email FROM user ORDER BY id DESC; return jdbcTemplate.query(sql, (rs, rowNum) - new User( rs.getLong(id), rs.getString(name), rs.getString(email) )); } // 更新操作返回受影响行数 public int updateEmail(Long id, String email) { String sql UPDATE user SET email ? WHERE id ?; return jdbcTemplate.update(sql, email, id); } // 删除操作 public int deleteById(Long id) { String sql DELETE FROM user WHERE id ?; return jdbcTemplate.update(sql, id); } }queryForObject在查不到数据时会抛出EmptyResultDataAccessException这是正常行为不建议用 try-catch 吞掉这个异常而是应该放行让全局异常处理器去映射成 404。RowMapper里的rs.getLong(id)是根据列名取值的如果你的 SQL 里用了别名比如SELECT id AS user_id那这里就要改成rs.getLong(user_id)否则会报Column not found错误。3.3 insert 返回自增主键插入数据并拿到自增主键是很常见的需求。JdbcTemplate 提供了KeyHolder机制可以避免先查再插的两次交互。public Long insertUser(User user) { String sql INSERT INTO user(name, email) VALUES (?, ?); GeneratedKeyHolder keyHolder new GeneratedKeyHolder(); jdbcTemplate.update(connection - { PreparedStatement ps connection.prepareStatement(sql, new String[]{id}); ps.setString(1, user.getName()); ps.setString(2, user.getEmail()); return ps; }, keyHolder); return keyHolder.getKey().longValue(); }这里prepareStatement(sql, new String[]{id})是告诉 MySQL 我们要返回 id 列的自增值。如果写成prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)在多列联合自增场景下可能取到错误的列。keyHolder.getKey()返回的是Number在 MySQL 下通常是Long但在某些数据库方言下可能是BigInteger所以用.longValue()转一下最保险。4. 连接池调参与排查事务边界、SSL 错误与驱动不兼容连接池和事务是 JDBC 方案里最容易出现翻车的地方。连接池参数设置不合理会表现为接口偶尔变慢、短暂卡顿后恢复事务边界没理清楚会出现数据写了但没提交或者报Transaction silently rolled back。这一章把连接池调优要点和常见问题的排查路径一并整理清楚。4.1 事务管理让多步操作保持原子性SpringBoot 里用Transactional声明事务非常方便但很多人不清楚它的默认回滚策略只回滚RuntimeException和Error受检异常比如IOException不会引起回滚而且事务会一直保持到方法结束。如果你在事务方法里 catch 到了异常而没抛出事务同样不会回滚但数据已经提交了。Service public class OrderService { private final JdbcTemplate jdbcTemplate; Transactional public void createOrder(Order order) { // 第一步插入订单主表 jdbcTemplate.update(INSERT INTO orders(user_id, total) VALUES (?, ?), order.getUserId(), order.getTotal()); // 第二步扣减库存 jdbcTemplate.update(UPDATE product SET stock stock - ? WHERE id ?, order.getProductId(), 1); // 这里如果抛出 RuntimeException两步都会回滚 } }事务参数里我建议关注rollbackFor和propagation两个属性。默认的propagation Propagation.REQUIRED在大多数场景下是对的即加入已有事务如果没有则新建。但如果你在事务方法里调用了另一个类的Transactional方法并且这个调用是通过this直接调用的Spring 的代理不会生效事务会失效。正确做法是通过注入的 Bean 或在同类内使用AopContext.currentProxy()。这个坑几乎每周都会有人在群里问一遍原因就是没理解代理机制。4.2 连接池参数怎么调根据压力而不是拍脑袋HikariCP 的核心参数需要结合业务场景来定。maximum-pool-size不是越大越好连接数过多时即使数据库端没有拒绝连接MySQL 的线程调度也会成为瓶颈。我通常的做法是先用压力测试工具如 JMeter施压观察响应时间和数据库 CPU 使用率然后逐渐增加连接数找到最优值。参数默认值建议调整方向minimum-idle10空闲连接数与最大连接数一致时池的响应最稳定maximum-pool-size10压测后按需调整一般 20 到 50 够用connection-timeout30000等待连接超时时间过短可能在高并发下误报超时idle-timeout600000空闲连接回收时间小于数据库 wait_timeout 即可max-lifetime1800000需小于数据库连接最大生命周期避免使用已断开连接常见错误是修改idle-timeout大于数据库的wait_timeout值。MySQL 的wait_timeout默认是 8 小时如果你的idle-timeout设置为 10 小时连接池认为连接还没到期但 MySQL 已经主动断开了这时候取出的连接会报Connection is not available或Communications link failure。稳妥的做法是让max-lifetime至少比数据库wait_timeout短 30 秒。4.3 避坑SSL 连接相关报错与驱动版本不兼容下面是几个比较高频的问题按「现象 → 原因 → 解决」的方式记录下来。问题一明明数据库能连却报 SSL 连接错误现象启动项目报SSLConnectionException: Unable to load default SSLContext或握手失败。原因MySQL 8.0 默认开启 SSL 加密连接而本地的 MySQL 未配置有效证书。URL 里没加useSSLfalse驱动尝试以 SSL 方式连接失败。解决在 JDBC URL 中明确添加useSSLfalse。如果公司安全要求必须开启 SSL则需准备证书并在连接串里指定sslModeVERIFY_CA和证书路径。问题二新装的 MySQL 8.0 连接报 Public Key Retrieval is not allowed现象连接时报SQLNonTransientConnectionException: Public Key Retrieval is not allowed。原因MySQL 8.0 默认密码插件是caching_sha2_password客户端第一次连接时需要获取服务器的 RSA 公钥如果客户端驱动不允许则直接失败。解决URL 追加allowPublicKeyRetrievaltrue。生产环境如果有更高安全要求可以在 MySQL 端将用户插件改为mysql_native_password但新驱动对这个插件的兼容性正在逐步调整。问题三驱动版本与 SpringBoot 版本不兼容启动报错或方法找不到现象项目启动时报NoClassDefFoundError或AbstractMethodError。原因SpringBoot 2.x 使用旧版mysql:mysql-connector-java依赖与 MySQL 8.0 的服务端协议不完全兼容SpringBoot 3.x 依赖包名改变为com.mysql:mysql-connector-j若存在不同版本的驱动被过滤器的类加载机制混用就会发生此错误。解决统一依赖坐标删除pom.xml中手动指定的旧驱动或在dependencyManagement中明确指定新版本。检查mvn dependency:tree是否有多个不同版本的驱动共存。问题四连接池连接突然全部无效接口批量报错现象系统运行一段时间后突然大量报Communications link failure或Connection reset重启后恢复。原因连接长时间空闲被 MySQL 服务端wait_timeout或中间网络设备关闭连接池里却还保留着这些废旧连接。解决设置合理的max-lifetime比 MySQLwait_timeout短并开启连接池的connection-test-queryHikariCP 默认自动开启MySQL 使用SELECT 1。5. 验证连接方式与压测配置最后要形成两个习惯项目配置完成后不能只是跑一次main方法看看启动日志就完事要形成一套可重复的验证流程。我的习惯是先做「连接有效性验证」再做「基础压力验证」两者通过之后才把配置提交到仓库。连接有效性的最简单办法是写一个ApplicationRunner的测试入口启动时自动执行一次查询。Component public class DatabaseConnectionChecker implements ApplicationRunner { private final JdbcTemplate jdbcTemplate; public DatabaseConnectionChecker(JdbcTemplate jdbcTemplate) { this.jdbcTemplate jdbcTemplate; } Override public void run(ApplicationArguments args) { Integer result jdbcTemplate.queryForObject(SELECT 1, Integer.class); if (result ! null result 1) { System.out.println(数据库连接校验通过); } } }这段代码里SELECT 1是连接池检测连接健康度的标准方式开销极低生产环境里的连接池每分钟都会执行一次。如果SELECT 1都失败说明连接已失效HikariCP 会从池中淘汰该连接并重建。接下来是压力验证。不要一上来就用 JMeter 打满 1000 并发而是先做小规模测试比如 50 并发持续 2 分钟观察三项指标接口 P99 响应时间、数据库 CPU 使用率、连接池的活跃连接数。若活跃连接数始终低于maximum-pool-size的 70%说明连接池宽裕可以考虑调小池子来减少资源浪费若活跃连接数打满且响应时间上升说明需要扩大最大连接数或者优化 SQL 索引。我最后想强调一个排查习惯每次遇到数据库连接相关的玄学问题先看SHOW PROCESSLIST和SHOW GLOBAL STATUS LIKE Threads_connected。这两个命令能立刻告诉你当前 MySQL 有多少连接、每个连接在干什么。如果Threads_connected数量异常高再看SHOW FULL PROCESSLIST里的Command和State字段要么是连接未释放要么是某个慢 SQL 长时间占用连接。从那以后我每次接触一个新的 SpringBoot MySQL 项目都会强制先跑一遍这两个命令做一次快照再开始看代码。这套方案里的源码和安装包也是奔着这个目的准备的——让你把环境问题在进入业务开发前一次性处理干净希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。