目录
- 环境准备
- 核心步骤与代码示例
- 完整可运行的示例
- 最佳实践 (使用
try-with-resources) - 使用连接池 (如 HikariCP)
- 常见问题与解决方案
环境准备
在开始编写代码之前,请确保您已经准备好以下环境:

-
Java Development Kit (JDK): 确保您的系统上已安装 JDK (推荐 JDK 8 或更高版本),并配置好
JAVA_HOME环境变量。 -
MySQL 服务器: 确保您的 MySQL 服务器正在运行。
-
MySQL 数据库: 在 MySQL 服务器上创建一个您要连接的数据库。
CREATE DATABASE my_test_db;
-
MySQL 用户和密码: 创建一个可以访问该数据库的用户,并授予其相应的权限。
(图片来源网络,侵删)-- 创建用户 'java_user',密码 'your_password',并允许从任何主机连接 CREATE USER 'java_user'@'%' IDENTIFIED BY 'your_password'; -- 授予 'java_user' 用户对 'my_test_db' 数据库的所有权限 GRANT ALL PRIVILEGES ON my_test_db.* TO 'java_user'@'%'; -- 刷新权限使更改生效 FLUSH PRIVILEGES;
-
MySQL JDBC 驱动程序 (JDBC Driver): 这是 Java 连接 MySQL 的桥梁。
- 下载: 访问 MySQL Connector/J 官方下载页面。
- 选择版本: 选择与您的 MySQL 服务器和 JDK 版本兼容的版本,最新的稳定版是最佳选择。
- 添加到项目: 将下载的
.jar文件添加到您的 Java 项目的类路径中。- 在 IDE (如 IntelliJ IDEA 或 Eclipse) 中: 右键点击项目 ->
Build Path/Project Structure->Libraries->Add External JARs...,然后选择下载的.jar文件。 - 使用 Maven (推荐): 在
pom.xml文件中添加以下依赖。<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> <!-- 请使用最新的稳定版本 --> </dependency> - 使用 Gradle: 在
build.gradle文件中添加以下依赖。implementation 'com.mysql:mysql-connector-j:8.0.33' // 请使用最新的稳定版本
- 在 IDE (如 IntelliJ IDEA 或 Eclipse) 中: 右键点击项目 ->
核心步骤与代码示例
JDBC 连接数据库的基本流程遵循以下步骤:
- 加载并注册 JDBC 驱动。
- 建立数据库连接。
- 创建
Statement或PreparedStatement对象。 - 执行 SQL 语句。
- 处理结果集 (如果是查询)。
- 关闭资源 (按与打开相反的顺序关闭)。
下面是一个详细的代码示例,展示了这些步骤。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcExample {
// --- 数据库连接信息 ---
// MySQL 8+ 的 URL 格式: jdbc:mysql://[host]:[port]/[database]?[propertyName1]=value1&[propertyName2]=value2
private static final String DB_URL = "jdbc:mysql://localhost:3306/my_test_db?useSSL=false&serverTimezone=UTC";
private static final String USER = "java_user";
private static final String PASS = "your_password";
public static void main(String[] args) {
// --- 1. 加载驱动 (对于现代JDBC驱动,这步通常是可选的,但写上总没错) ---
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.err.println("找不到 MySQL JDBC 驱动!");
e.printStackTrace();
return;
}
// --- 2. 建立连接 ---
// 使用 try-with-resources 确保 Connection 对象在使用后被自动关闭
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {
System.out.println("数据库连接成功!");
// --- 3. 创建 Statement 并执行查询 ---
// 使用 try-with-resources 确保 Statement 和 ResultSet 对象被自动关闭
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name, email FROM users")) {
System.out.println("--- 用户列表 ---");
// --- 4. 处理结果集 ---
while (rs.next()) {
// 通过列名获取数据,更具可读性且不易出错
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
System.out.println("ID: " + id + ", 姓名: " + name + ", 邮箱: " + email);
}
}
// --- 使用 PreparedStatement (推荐,防止SQL注入) ---
String insertSql = "INSERT INTO users (name, email) VALUES (?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
// 设置参数
pstmt.setString(1, "张三");
pstmt.setString(2, "zhangsan@example.com");
// 执行更新
int affectedRows = pstmt.executeUpdate();
System.out.println("\n成功插入 " + affectedRows + " 行数据。");
}
} catch (SQLException e) {
System.err.println("数据库操作出错!");
e.printStackTrace();
}
}
}
完整可运行的示例
假设您已经按照 环境准备 步骤创建了数据库、用户,并添加了 JDBC 驱动。

-
创建表:
USE my_test_db; CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL UNIQUE ); -
运行上面的
JdbcExample.java代码。 -
预期输出:
数据库连接成功! --- 用户列表 --- 成功插入 1 行数据。如果您再次运行,第二次运行时查询会显示刚插入的 "张三"。
最佳实践 (使用 try-with-resources)
手动关闭 Connection, Statement, 和 ResultSet 是非常繁琐且容易忘记的,这可能导致资源泄露,从 Java 7 开始,推荐使用 try-with-resources 语句,它可以确保任何实现了 AutoCloseable 接口的对象在语句块结束时都会被自动关闭。
这是修改后的最佳实践代码,它更安全、更简洁:
import java.sql.*;
public class JdbcBestPracticeExample {
private static final String DB_URL = "jdbc:mysql://localhost:3306/my_test_db?useSSL=false&serverTimezone=UTC";
private static final String USER = "java_user";
private static final String PASS = "your_password";
public static void main(String[] args) {
// Connection, Statement, ResultSet 都在 try-with-resources 中声明
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name, email FROM users")) {
System.out.println("数据库连接成功!");
System.out.println("--- 用户列表 ---");
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
System.out.println("ID: " + id + ", 姓名: " + name + ", 邮箱: " + email);
}
} catch (SQLException e) {
System.err.println("数据库操作出错!");
e.printStackTrace();
}
}
}
使用连接池 (如 HikariCP)
在真实的应用程序中,为每个请求创建和销毁数据库连接是非常消耗资源的。数据库连接池 应运而生,它预先创建一组数据库连接,并将它们保存在池中,当需要连接时,从池中获取,用完后归还给池,而不是关闭。
HikariCP 是目前性能最好的 Java 连接池之一。
步骤:
- 添加 HikariCP 依赖 (Maven):
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>5.0.1</version> <!-- 使用最新版本 --> </dependency> - 编写使用 HikariCP 的代码:
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcWithHikariCP {
private static HikariDataSource dataSource;
// 初始化连接池
static {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/my_test_db?useSSL=false&serverTimezone=UTC");
config.setUsername("java_user");
config.setPassword("your_password");
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
// 连接池优化配置 (根据实际情况调整)
config.setMaximumPoolSize(10); // 最大连接数
config.setMinimumIdle(5); // 最小空闲连接数
config.setConnectionTimeout(30000); // 连接超时时间 (毫秒)
config.setIdleTimeout(600000); // 空闲连接超时时间 (毫秒)
config.setMaxLifetime(1800000); // 连接最大存活时间 (毫秒)
dataSource = new HikariDataSource(config);
}
public static void main(String[] args) {
// 从连接池获取连接
try (Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name FROM users")) {
System.out.println("从连接池成功获取连接!");
while (rs.next()) {
System.out.println("ID: " + rs.getInt("id") + ", 姓名: " + rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
常见问题与解决方案
-
ClassNotFoundException: com.mysql.cj.jdbc.Driver- 原因: JDBC 驱动
.jar文件没有被添加到项目的类路径中。 - 解决: 检查并确保已正确将 MySQL Connector/J 的 JAR 包添加到项目中。
- 原因: JDBC 驱动
-
SQLException: The server time zone value '�й���ʱ��' is unrecognized- 原因: MySQL 服务器和 Java 客户端之间的时区不一致。
- 解决: 在 JDBC URL 中明确指定服务器时区,使用
UTC时区。String DB_URL = "jdbc:mysql://localhost:3306/my_test_db?serverTimezone=UTC";
-
SQLException: Access denied for user 'user'@'host'- 原因: 用户名、密码错误,或者该用户没有从您正在连接的客户端主机访问数据库的权限。
- 解决:
- 检查用户名和密码是否正确。
- 在 MySQL 中,确保用户已创建并授予了正确的权限,如果从本地连接,主机名可能是
localhost或0.0.1。
-
Communications link failure- 原因: 无法连接到 MySQL 服务器。
- 解决:
- 确认 MySQL 服务器正在运行。
- 检查防火墙是否阻止了连接端口 (默认为 3306)。
- 确认 JDBC URL 中的主机名和端口号是否正确。
| 场景 | 推荐方法 | 优点 | 缺点 |
|---|---|---|---|
| 学习/测试 | DriverManager + try-with-resources |
简单直接,无需额外依赖 | 不适合高并发,性能差 |
| 生产环境/高并发 | 连接池 (如 HikariCP) | 高性能、高可靠、资源复用 | 需要额外引入依赖,配置稍复杂 |
对于任何严肃的 Java 应用程序,强烈建议使用数据库连接池。try-with-resources 是编写健壮 JDBC 代码的标配。
