做过 Java 后端的同学应该都有体会,数据库交互这块几乎是绕不过去的坎。不管是刚学 Java 基础,还是准备面试八股文,“Java 连接 MySQL 数据库并实现数据交互”都是最常被拿出来考的场景。今天这篇博文,我就把从零开始用 JDBC 操作 MySQL 的完整链路拆开,从驱动选型到代码落地,从连接工具类到增删改查,从常见报错到排查思路,一次性讲清楚。
写这篇文章的初衷很直接:网上的教程要么只贴代码不给解释,要么把 JDBC 讲成天书。我这些年带新人、自己踩坑,积累了不少行之有效的实操套路,今天全部整理出来。无论你是刚接触 Java 的初学者,还是在准备 Java 面试、需要手写 JDBC 代码的求职者,亦或是做数据库课程设计需要快速落地项目的学生,这篇文章都能直接帮你省掉大把试错时间。
1. 整体设计与方案选型
1.1 先理清楚:Java 操作 MySQL 到底有哪些路
先别急着写代码,搞明白几个选择。Java 生态里操作数据库的方案,我粗略分成三层:
- 最底层:JDBC,Java Database Connectivity,这是 Java 访问数据库的官方标准接口,也是所有上层框架的基石。
- 中间层:Spring JDBC(
JdbcTemplate)、Apache DBUtils 这类轻量封装,极大减少样板代码,但仍然要手动处理连接、结果集到对象的映射。 - 上层:MyBatis、MyBatis-Plus、Hibernate 这类 ORM 框架,把数据库表和 Java 对象映射起来,开发者写 SQL 或 HQL 即可,连接管理、结果映射都交给框架。
很多初学者一上来就学 MyBatis,这是走偏了。
先说我的观点:不管你用不用框架,JDBC 都值得亲手写一遍。 原因有三:
- 你迟早会遇到底层报错。
ClassNotFoundException、SQLException、驱动版本不兼容这类问题,不懂 JDBC 的连接机制,你连排查方向都没有。 - 面试官最爱抠细节。Java 面试题里十有八九会问到 JDBC 的六步流程、
Statement和PreparedStatement的区别、事务的提交与回滚,这些全是 JDBC 层面的东西。 - 自己写的代码出问题时,你会发现所有 ORM 框架本质都是「包装好的 JDBC」,翻到框架源码最底层,依然是
DriverManager拿连接、PreparedStatement执行 SQL、ResultSet遍历结果。
所以本文以原生 JDBC 为核心,后续如果有需要,再单独写框架整合篇。
1.2 JDBC 的底层逻辑:连接到底在连接什么
JDBC 的连接本质,是 Java 进程通过 TCP/IP 协议,和 MySQL 服务端的 3306 端口建立一条可通信的通道。MySQL 在这条通道上完成身份认证、字符集协商,之后你就可以通过这条通道发送 SQL 指令、接收结果集。
流程简化之后就是一套固定模板:
- 加载并注册数据库驱动。
- 通过
DriverManager获取数据库连接Connection。 - 通过连接创建
Statement/PreparedStatement。 - 执行 SQL 并返回结果。
- 遍历
ResultSet处理数据。 - 依次关闭
ResultSet、Statement、Connection。
这个六步流程,就是 Java 面试题里常考的「JDBC 操作数据库步骤」,也是整个数据交互的核心原理。
但这里有个关键点:真正干活的是 MySQL 的 Connector/J 驱动包,而不是 JDK 本身。JDK 只定义了接口(java.sql.*),驱动厂商负责实现。所以第一步「加载驱动」的意思是,把 mysql-connector-java 这个 jar 包引入项目,然后通过 Class.forName("com.mysql.cj.jdbc.Driver") 把驱动类加载进 JVM。
在较新的 JDBC 4.0 规范下,驱动可以自动注册,Class.forName 这一步都不写也能连上,只要 classpath 里有驱动 jar 包即可。但为了兼容性和可读性,我仍然建议显式写出来,这能体现你对连接机制的理解。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与驱动选型
2.1 MySQL 版本和驱动版本怎么搭才不踩坑
很多报错的根源,都在版本不匹配上。如果让我推荐一个稳妥组合,现阶段我倾向于:
| 组件 | 推荐版本 |
|---|---|
| MySQL Server | 5.7 或 8.0(8.0 为主流) |
| mysql-connector-java | 8.0.x(与 MySQL 8.x 强匹配) |
| JDK | 8 / 11 / 17 均兼容 |
| Maven | 3.6+ |
为什么 MySQL 5.7 和 8.0 要区分对待?关键在于 8.0 的默认认证插件换成了 caching_sha2_password,老版本的驱动(5.1.x)不支持这个协议,会直接报出类似 Unable to load authentication plugin 'caching_sha2_password' 的错误。解决方式有两种:
- 升级驱动到 8.0.20 以上。
- 在 MySQL 里把用户的认证插件改回
mysql_native_password(不推荐长期用,但这确实能救急)。
我在实际项目中遇到过 FireDAC 连接 MySQL 时也报握手协议不支持的问题,这时候去检查 MySQL 版本和客户端库是否配套,方向基本没错。顺手记一下:Windows 下安装 MySQL 后,把 bin 目录加到系统 PATH,不然命令行老是要切路径。
2.2 Maven 依赖与本地 jar 的两种引入方式
不管你是用 IntelliJ IDEA 还是 Eclipse,引入驱动有两种场景。
场景一:Maven 项目
在 pom.xml 中添加依赖:
xml复制<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
这里有个小坑:新版 Maven 坐标里有时用 com.mysql:mysql-connector-j,这是官方后续改的产物名。如果你在公司老项目里看到 <artifactId>mysql-connector-java</artifactId>,不用慌,两套坐标都能用,只是不同发行版本的差异。
场景二:非 Maven 项目
去 MySQL 官网下载 mysql-connector-j 的 jar 包,
