上一篇
Java JDBC需先加载数据库驱动,创建数据库连接,再通过Statement或PreparedStatement执行SQL语句,处理结果集后关闭资源
如何使用Java JDBC进行数据库操作
Java JDBC(Java Database Connectivity)是Java提供的标准API,用于连接和操作各种关系型数据库,它通过统一的接口屏蔽了不同数据库的差异,使开发者能够专注于业务逻辑,以下是使用JDBC的详细步骤、核心组件及注意事项。
JDBC的核心组件
| 组件 | 功能描述 |
|---|---|
java.sql.Driver |
数据库驱动,负责将JDBC API转换为特定数据库的协议(如MySQL、Oracle)。 |
java.sql.DriverManager |
管理驱动的加载和连接获取。 |
java.sql.Connection |
代表与数据库的连接,用于发送SQL语句和事务管理。 |
java.sql.Statement |
执行静态SQL语句(如SELECT、INSERT),每次执行需重新编译SQL。 |
java.sql.PreparedStatement |
预编译SQL语句,支持参数化查询,防止SQL注入并提高性能。 |
java.sql.ResultSet |
存储查询结果集,支持逐行遍历和数据提取。 |
使用JDBC的详细步骤
以下是通过JDBC连接MySQL数据库并执行增删查改操作的完整流程:
加载数据库驱动
在JDBC 4.0及以上版本中,驱动通常会自动加载,但显式加载仍推荐用于兼容性。
try {
Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL驱动类名
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
说明:

- 不同数据库的驱动类名不同(如PostgreSQL为
org.postgresql.Driver)。 - 如果使用JDBC 4.0+且驱动在类路径中,可省略此步骤。
建立数据库连接
通过DriverManager获取连接对象。
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC";
String username = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, username, password)) {
System.out.println("连接成功!");
// 后续操作...
} catch (SQLException e) {
e.printStackTrace();
}
关键点:
- URL格式:
jdbc:数据库类型://主机:端口/数据库名?参数。 - 参数示例:
useSSL=false禁用SSL,serverTimezone=UTC解决时区问题。
创建Statement或PreparedStatement
- Statement:适用于静态SQL语句。
String sql = "SELECT FROM users"; try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); System.out.println("ID: " + id + ", Name: " + name); } } - PreparedStatement:适用于参数化查询,防止SQL注入。
String insertSql = "INSERT INTO users (name, email) VALUES (?, ?)"; try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) { pstmt.setString(1, "Alice"); pstmt.setString(2, "alice@example.com"); int rows = pstmt.executeUpdate(); System.out.println("插入了 " + rows + " 行数据"); }
执行SQL语句
executeQuery():用于SELECT语句,返回ResultSet。executeUpdate():用于INSERT、UPDATE、DELETE,返回受影响的行数。
处理结果集(ResultSet)
while (rs.next()) {
// 通过列名或索引获取数据
String name = rs.getString("name");
int age = rs.getInt(1); // 第一列(索引从1开始)
}
注意事项:

ResultSet的游标默认位于第一行之前,需调用next()移动到有效行。- 关闭
ResultSet后无法读取数据。
事务管理
通过Connection对象控制事务提交或回滚。
try {
conn.setAutoCommit(false); // 关闭自动提交
// 执行多条SQL语句...
conn.commit(); // 提交事务
} catch (SQLException e) {
conn.rollback(); // 回滚事务
e.printStackTrace();
}
关闭资源
使用try-with-resources自动关闭资源,避免内存泄漏。
try (Connection conn = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 执行操作...
} catch (SQLException e) {
e.printStackTrace();
}
手动关闭示例:

if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close();
常见问题与解决方案
SQL注入攻击
- 原因:直接拼接用户输入到SQL语句中。
- 解决方案:使用
PreparedStatement的参数化查询。String safeSql = "SELECT FROM users WHERE id = ?"; try (PreparedStatement pstmt = conn.prepareStatement(safeSql)) { pstmt.setInt(1, userId); // 自动转义特殊字符 ResultSet rs = pstmt.executeQuery(); }
连接泄漏
- 原因:未及时关闭连接或异常导致资源未释放。
- 解决方案:
- 使用
try-with-resources语句。 - 在
finally块中手动关闭资源。
- 使用
驱动未找到
- 错误:
ClassNotFoundException: com.mysql.cj.jdbc.Driver。 - 解决方案:
- 检查驱动是否添加到项目类路径(如Maven依赖)。
- 确认驱动类名正确(如MySQL为
com.mysql.cj.jdbc.Driver)。
FAQs
Q1:如何选择合适的JDBC驱动?
A1:根据数据库类型选择对应驱动,
- MySQL:
mysql-connector-java。 - PostgreSQL:
postgresql。 - Oracle:
ojdbc。
将驱动JAR包添加到项目类路径或依赖管理工具(如Maven)中。
Q2:为什么推荐使用PreparedStatement而不是Statement?
A2:主要原因包括:
- 安全性:避免SQL注入攻击。
- 性能:预编译SQL语句,减少重复解析开销。
- 灵活性:支持动态
