Java案例如何连接MySQL数据库?从入门到实战的完整指南
目录导读
连接MySQL的核心原理与前置准备
在任何一个企业级Java项目中,数据库连接都是最基础也最关键的环节。Java通过JDBC(Java Database Connectivity) 这一标准API与MySQL数据库进行交互,JDBC相当于一个“数据库驱动程序管理器”,不同的数据库厂商(如MySQL、Oracle)会提供对应的JDBC驱动实现。

前置环境要求
- JDK版本:建议1.8及以上,Java 11/17更佳
- MySQL版本:5.7+ 或 8.0+(推荐8.0)
- MySQL JDBC驱动:mysql-connector-java (最新版本为mysql-connector-j)
下载地址:Maven中央仓库或MySQL官方站点 - 开发工具:IntelliJ IDEA / Eclipse / VS Code 均可
安装MySQL数据库(不赘述)
如果你尚未安装MySQL,可使用 brew install mysql (Mac) 或 apt-get install mysql-server (Linux),Windows用户建议使用官方安装包,安装后创建测试数据库:
CREATE DATABASE mydb;
USE mydb;
CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), email VARCHAR(100));
INSERT INTO users(name,email) VALUES('Alice','alice@example.com'),('Bob','bob@example.com');
问与答
Q:为什么需要JDBC驱动?
A:JDBC驱动是“翻译官”,Java代码发送SQL指令时,驱动负责将指令转换成MySQL能理解的原生协议,并返回结果集,没有驱动,Java无法与MySQL直接对话。
JDBC驱动加载与数据库URL配置详解
1 驱动加载方式演变
在JDBC 4.0前,需要手动 Class.forName("com.mysql.jdbc.Driver") 注册驱动。
而从JDBC 4.0 (Java 6) 开始,只要jar包在classpath中,DriverManager能自动加载驱动,无需显式调用。
2 MySQL JDBC URL标准格式
jdbc:mysql://[host]:[port]/[database]?[参数键值对]
常见参数(MySQL 8.0推荐):
useSSL=false:开发环境关闭SSL加密,避免证书问题serverTimezone=Asia/Shanghai:解决时区错误allowPublicKeyRetrieval=true:MySQL 8.0+ 允许从服务器获取公钥characterEncoding=UTF-8:确保中文不乱码
示例:
String url = "jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
问与答
Q:连接MySQL 8.0时总报“Public Key Retrieval is not allowed”怎么办?
A:在URL末尾追加allowPublicKeyRetrieval=true,这是MySQL 8.0的安全policy变更,驱动默认不允许直接获取公钥。
Java连接MySQL的经典代码案例(含图文步骤)
下面给出一个完整的、可直接运行的Java连接MySQL并执行查询的例子。
步骤1:在项目中添加MySQL驱动依赖
Maven用户(在pom.xml中添加):
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
Gradle用户:
implementation 'mysql:mysql-connector-java:8.0.33'
注意:MySQL官方从2024年起将旧包
mysql-connector-java重命名为mysql-connector-j,但向后兼容性良好。
步骤2:编写Java连接代码
import java.sql.*;
public class MySQLConnectionDemo {
// 数据库配置(建议从配置文件读取,此处仅为演示)
private static final String URL = "jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";
private static final String USER = "root";
private static final String PASSWORD = "your_password";
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// 1. 加载驱动(JDBC 4.0+ 可省略)
// Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 获取数据库连接
connection = DriverManager.getConnection(URL, USER, PASSWORD);
System.out.println("✅ 数据库连接成功!");
// 3. 创建Statement对象
statement = connection.createStatement();
// 4. 执行SQL查询
String sql = "SELECT * FROM users";
resultSet = statement.executeQuery(sql);
// 5. 处理结果集
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String email = resultSet.getString("email");
System.out.printf("ID: %d, Name: %s, Email: %s%n", id, name, email);
}
} catch (SQLException e) {
System.err.println("❌ 数据库错误:" + e.getMessage());
e.printStackTrace();
} finally {
// 6. 关闭资源(遵循“后开先关”原则)
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
System.out.println("🔒 连接已关闭");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
步骤3:运行与测试
控制台输出示例:
✅ 数据库连接成功!
ID: 1, Name: Alice, Email: alice@example.com
ID: 2, Name: Bob, Email: bob@example.com
🔒 连接已关闭
问与答
Q:为什么不建议直接用Statement而用PreparedStatement?
A:Statement存在SQL注入风险。"SELECT * FROM users WHERE name='" + userName + "'",PreparedStatement通过预编译和参数绑定,能有效防御注入攻击,且批量执行时性能更好。
常见连接失败问题排查与问答
问题1:ClassNotFoundException: com.mysql.cj.jdbc.Driver
原因:未将mysql-connector-java.jar放入classpath。
解决:检查Maven/Gradle依赖是否已下载,或手动添加jar到项目库。
问题2:Access denied for user 'root'@'localhost'
原因:用户名或密码错误,或MySQL的认证插件不兼容。
解决:检查用户名密码;若为MySQL 8.0,尝试在URL中添加 useLegacyDatetimeCode=false,或修改root密码策略:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';
问题3:The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized
原因:MySQL时区设置与Java不匹配。
解决:设置URL参数 serverTimezone=Asia/Shanghai 或 serverTimezone=UTC。
问题4:连接超时(connect timed out)
原因:MySQL服务未启动,或端口被防火墙拦截,或主机地址错误。
解决:检查 systemctl status mysql;使用 telnet localhost 3306 测试端口连通性。
问与答
Q:如何检查MySQL服务是否在运行?
A:进入MySQL命令行mysql -u root -p,若能进入则服务正常,或使用系统命令systemctl is-active mysql(Linux) /Get-Service MySQL*(Windows PowerShell)。
性能优化与安全最佳实践
1 使用连接池(高并发必备)
每次建立数据库连接都非常昂贵(TCP握手、认证等),在生产环境中,请用连接池代替每次都创建新连接。
常见连接池:HikariCP(Spring Boot默认)、Druid、C3P0。
HikariCP示例(无框架时):
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
HikariConfig config = new HikariConfig(); config.setJdbcUrl(URL); config.setUsername(USER); config.setPassword(PASSWORD); config.setMaximumPoolSize(20); HikariDataSource dataSource = new HikariDataSource(config); Connection conn = dataSource.getConnection(); // 从池中获取
2 永远不要在代码中写死密码
将数据库配置存放到 application.properties 或环境变量 DATABASE_URL 中。
使用配置中心(如Spring Cloud Config)或密码加密工具(如jasypt)。
3 使用try-with-resources自动关闭连接
Java 7+ 提供了更简洁的资源管理方式:
try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
ResultSet rs = ps.executeQuery()) {
ps.setInt(1, 1);
while (rs.next()) { /* ... */ }
} // 自动关闭所有资源
4 区分开发环境与生产环境
- 开发:
useSSL=false, serverTimezone=Asia/Shanghai - 生产:必须启用SSL,添加
useSSL=true&requireSSL=true,并配置证书路径。
最终总结
连接MySQL是Java后端开发的“必修课”,从理解JDBC驱动加载、配置URL,到编写健壮的连接代码,再到接入连接池和安全处理,每一步都影响着应用的稳定与安全。
建议读者将文中的代码案例复制到IDE中运行一次,并尝试修改参数(比如连接错误时观察异常信息),只有亲手踩过坑,才能真正掌握。