JDBC 入门教程:零基础掌握 Java 数据库连接
一、什么是 JDBC?
JDBC (Java Database Connectivity) 是 Java 提供的标准 API,用于连接和操作各种关系型数据库(如 MySQL, Oracle, PostgreSQL 等)。它就像 Java 程序与数据库之间的"翻译官"。
二、准备工作
-
安装数据库(以 MySQL 为例):
-
安装时记住 root 密码
-
创建测试数据库:
-- 创建数据库 CREATE DATABASE jdbc_test; -- 使用数据库 USE jdbc_test; -- 创建用户表 CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL ); -- 插入初始数据 INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com'), ('李四', 'lisi@example.com');
-
下载 JDBC 驱动:
-
选择 Platform Independent 版本(.jar 文件)
-
添加驱动到项目:
-
Eclipse/IntelliJ:将 JAR 文件添加到项目的库依赖中
-
命令行编译:
javac -cp ".;mysql-connector-java-8.0.xx.jar" YourFile.java
-
三、JDBC 核心步骤(7步法)
1. 注册驱动(JDBC 4.0+ 自动完成)
// JDBC 4.0 之前的传统加载方式
// Class.forName("com.mysql.cj.jdbc.Driver");
2. 建立数据库连接
// 数据库连接配置
String url = "jdbc:mysql://localhost:3306/jdbc_test?useSSL=false&serverTimezone=UTC";
String username = "root";
String password = "your_password";
// 建立数据库连接
try (Connection connection = DriverManager.getConnection(url, username, password)) {
System.out.println("数据库连接成功!");
// 执行数据库操作...
} catch (SQLException e) {
System.out.println("数据库连接失败:" + e.getMessage());
}
连接字符串说明:
jdbc:mysql://
:JDBC协议
localhost:3306
:数据库地址和端口
/jdbc_test
:数据库名
?useSSL=false
:禁用SSL(测试用)
&serverTimezone=UTC
:设置时区(避免时间错误)
3. 创建 Statement 对象
try (Statement stmt = conn.createStatement()) {
// 执行SQL操作...
}
4. 执行 SQL 查询
String sql = "SELECT * FROM users";
ResultSet rs = stmt.executeQuery(sql);
5. 处理查询结果
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
System.out.printf("ID: %d, 姓名: %s, 邮箱: %s%n", id, name, email);
}
6. 执行更新操作
// 数据插入操作
String insertSQL = "INSERT INTO users (name, email) VALUES ('王五', 'wangwu@test.com')";
int affectedRows = stmt.executeUpdate(insertSQL);
System.out.println("成功插入 " + affectedRows + " 条记录");
// 数据更新操作
String updateSQL = "UPDATE users SET email='lisi_new@test.com' WHERE name='李四'";
affectedRows = stmt.executeUpdate(updateSQL);
7. 释放资源(自动关闭)
使用 try-with-resources 语法(Java 7+),资源会自动关闭:
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
// 业务逻辑处理
} catch (SQLException e) {
e.printStackTrace();
}
四、完整示例代码
import java.sql.*;
public class JdbcDemo {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/jdbc_test?useSSL=false&serverTimezone=UTC";
String user = "root";
String password = "your_password"; // 请替换为实际密码
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement()) {
// 查询用户数据
System.out.println("===== 用户列表 =====");
try (ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
while (rs.next()) {
System.out.println(rs.getInt("id") + "\t"
+ rs.getString("name") + "\t"
+ rs.getString("email"));
}
}
// 插入新用户
String insertSQL = "INSERT INTO users (name, email) VALUES ('赵六', 'zhaoliu@test.com')";
int rows = stmt.executeUpdate(insertSQL);
System.out.println("\n成功插入 " + rows + " 条记录");
// 显示更新后的用户列表
System.out.println("\n===== 更新后的用户列表 =====");
try (ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
while (rs.next()) {
System.out.println(rs.getInt("id") + "\t"
+ rs.getString("name") + "\t"
+ rs.getString("email"));
}
}
} catch (SQLException e) {
System.err.println("数据库操作异常: " + e.getMessage());
}
}
}
五、运行结果示例
===== 用户列表 =====
1 张三 zhangsan@example.com
2 李四 lisi@example.com
插入了 1 行数据
===== 更新后的用户列表 =====
1 张三 zhangsan@example.com
2 李四 lisi@example.com
3 赵六 zhaoliu@test.com
六、下一步学习建议
-
使用 PreparedStatement 防止 SQL 注入
// 使用PreparedStatement进行安全的数据库插入操作示例 String sql = "INSERT INTO users (name, email) VALUES (?, ?)"; // 定义SQL插入语句,使用参数化查询防止SQL注入 try (Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/mydatabase", "username", "password"); PreparedStatement pstmt = conn.prepareStatement(sql)) { // 使用try-with-resources自动关闭资源 // 设置第一个参数(姓名)为"新用户",对应SQL中的第一个? pstmt.setString(1, "新用户"); // 设置第二个参数(邮箱)为"new@user.com",对应SQL中的第二个? pstmt.setString(2, "new@user.com"); // 执行SQL更新,返回受影响的行数 int affectedRows = pstmt.executeUpdate(); System.out.println("成功插入记录,受影响行数:" + affectedRows); } catch (SQLException e) { // 处理可能出现的数据库异常 System.err.println("数据库操作出错:" + e.getMessage()); e.printStackTrace(); } /
-
事务处理
// 典型的事务处理代码示例 Connection conn = DriverManager.getConnection(url, username, password); conn.setAutoCommit(false); // 关闭自动提交,开启事务模式 try { // 执行第一个SQL操作 PreparedStatement stmt1 = conn.prepareStatement("UPDATE accounts SET balance = balance - ? WHERE id = ?"); stmt1.setInt(1, 100); stmt1.setInt(2, 1); stmt1.executeUpdate(); // 执行第二个SQL操作 PreparedStatement stmt2 = conn.prepareStatement("UPDATE accounts SET balance = balance + ? WHERE id = ?"); stmt2.setInt(1, 100); stmt2.setInt(2, 2); stmt2.executeUpdate(); conn.commit(); // 提交事务,完成转账操作 System.out.println("事务提交成功,转账完成"); } catch (SQLException e) { conn.rollback(); // 发生异常时回滚事务,保证数据一致性 System.err.println("事务执行失败,已回滚:" + e.getMessage()); } finally { try { conn.setAutoCommit(true); // 恢复自动提交模式 conn.close(); // 关闭连接 } catch (SQLException e) { e.printStackTrace(); } }
-
连接池技术(如 HikariCP)
/** * HikariCP数据库连接池配置示例 * * 1. 创建HikariConfig配置对象 * 2. 设置数据库连接参数 * 3. 创建数据源并获取连接 * 4. 使用try-with-resources自动管理资源 */ public class DatabaseConnectionExample { public static void main(String[] args) { // 数据库连接配置参数 String url = "jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=UTC"; String user = "root"; String password = "password123"; // 1. 创建HikariCP配置对象 HikariConfig config = new HikariConfig(); // 2. 配置数据库连接参数 config.setJdbcUrl(url); // 设置JDBC连接URL config.setUsername(user); // 设置数据库用户名 config.setPassword(password);// 设置数据库密码 // 可选配置项示例: config.setMaximumPoolSize(10); // 设置最大连接数 config.setConnectionTimeout(30000); // 设置连接超时时间(毫秒) config.setIdleTimeout(600000); // 设置空闲连接超时时间 // 3. 创建数据源并获取连接 try ( // 创建HikariDataSource数据源 HikariDataSource ds = new HikariDataSource(config); // 从连接池获取连接 Connection conn = ds.getConnection(); // 创建Statement对象 Statement stmt = conn.createStatement() ) { // 4. 使用数据库连接执行SQL ResultSet rs = stmt.executeQuery("SELECT * FROM users"); // 处理查询结果... while (rs.next()) { System.out.println("User ID: " + rs.getInt("id")); System.out.println("Username: " + rs.getString("username")); } } catch (SQLException e) { // 异常处理 e.printStackTrace(); } // try-with-resources会自动关闭连接、释放资源 } }
七、常见问题解决
-
驱动未找到:
-
确认 JAR 文件已添加到类路径
-
检查驱动类名是否正确(MySQL 8.x:
com.mysql.cj.jdbc.Driver
)
-
-
时区问题:
-
在连接字符串添加
&serverTimezone=UTC
-
-
SSL 警告:
-
测试环境可添加
useSSL=false
-
生产环境应使用有效证书
-
-
中文乱码:
-
添加参数:
&characterEncoding=UTF-8
-
提示:生产环境中务必:
使用 PreparedStatement 防止 SQL 注入
配置合适的连接池
将数据库凭证存储在安全位置(非代码中)
启用 SSL 加密连接