1. JDBC 概述
- JDBC (Java Database Connectivity) 是 Java 提供的用于操作关系型数据库的标准 API。
- 核心功能:连接数据库、执行 SQL、处理结果集。
驱动类型:
- Type 1:JDBC-ODBC 桥接(已淘汰)。
- Type 2:本地 API 驱动(如 Oracle OCI)。
- Type 3:网络协议驱动(如旧版 MySQL Connector/J)。
- Type 4:纯 Java 驱动(主流,如
mysql-connector-java
)。
2. JDBC 核心接口与类
接口/类 | 作用 |
---|---|
DriverManager | 管理数据库驱动,建立连接。 |
Connection | 表示与数据库的会话。 |
Statement | 执行静态 SQL 语句(存在 SQL 注入风险)。 |
PreparedStatement | 预编译 SQL 语句(防注入,高效复用)。 |
CallableStatement | 调用存储过程。 |
ResultSet | 封装查询结果集。 |
ResultSetMetaData | 获取结果集的元信息(列名、类型等)。 |
3. JDBC 操作流程
加载驱动
Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL 驱动类
建立连接
String url = "jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC"; String user = "root"; String password = "123456"; Connection conn = DriverManager.getConnection(url, user, password);
创建 Statement
Statement stmt = conn.createStatement(); // 静态 SQL PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users WHERE id=?"); // 预编译
执行 SQL
查询:
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
更新(INSERT/UPDATE/DELETE):
int rows = stmt.executeUpdate("DELETE FROM users WHERE age < 18");
处理结果集
while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); System.out.println(id + ": " + name); }
关闭资源
rs.close(); stmt.close(); conn.close(); // 必须按顺序关闭(后开先关)
4. PreparedStatement 防止 SQL 注入
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, userInputName); // 参数索引从 1 开始
pstmt.setString(2, userInputPass);
ResultSet rs = pstmt.executeQuery();
5. 事务管理
try {
conn.setAutoCommit(false); // 关闭自动提交
// 执行多个 SQL 操作...
conn.commit(); // 提交事务
} catch (SQLException e) {
conn.rollback(); // 回滚事务
} finally {
conn.setAutoCommit(true); // 恢复默认
}
6. 结果集元数据(动态处理未知表结构)
ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
String columnName = meta.getColumnName(i);
String columnType = meta.getColumnTypeName(i);
System.out.println(columnName + " (" + columnType + ")");
}
7. 连接池(以 HikariCP 为例)
添加依赖:
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>5.0.1</version> </dependency>
配置与使用:
HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb"); config.setUsername("root"); config.setPassword("123456"); config.setMaximumPoolSize(10); // 最大连接数 try (HikariDataSource dataSource = new HikariDataSource(config); Connection conn = dataSource.getConnection()) { // 使用连接... }
8. 常见异常与解决
ClassNotFoundException: com.mysql.jdbc.Driver
- 原因:未添加数据库驱动 JAR 包。
- 解决:检查项目依赖或 Classpath。
SQLException: Connection refused
- 原因:数据库服务未启动或网络不通。
- 解决:检查数据库状态、端口及防火墙设置。
SQLSyntaxErrorException
- 原因:SQL 语句语法错误。
- 解决:打印 SQL 并手动验证。
9. 最佳实践
资源释放:
使用try-with-resources
自动关闭资源(Java 7+):try (Connection conn = DriverManager.getConnection(url); PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery()) { // 操作数据... }
- 避免 SELECT *:
明确指定查询字段,减少网络传输开销。 批量处理:
pstmt.addBatch(); // 添加批处理 pstmt.executeBatch(); // 执行批处理
10. 总结
- JDBC 是 Java 操作数据库的基石,需掌握核心接口与流程。
- 优先使用
PreparedStatement
防注入,结合连接池提升性能。 - 事务管理和资源释放是保证数据一致性和稳定性的关键。
评论 (0)