1. JDBC概述
JDBC(Java Database Connectivity)是Java提供的一种数据库连接技术,用于在Java应用程序中与数据库进行交互。它通过一组API提供了访问和操作数据库的标准方式。JDBC支持大多数关系型数据库,包括MySQL、Oracle、SQL Server等。
JDBC的主要作用是:
-
连接数据库。
-
执行SQL语句(包括查询、更新、删除等)。
-
获取查询结果。
-
提交或回滚事务。
JDBC是Java程序与数据库之间的桥梁,任何基于Java的应用程序如果需要和数据库进行数据交互,都会使用JDBC技术。
2. JDBC的核心组件
JDBC的核心组成包括:
-
DriverManager:管理数据库驱动程序。
-
Connection:表示与数据库的连接。
-
Statement:用于执行SQL语句。
-
ResultSet:存储查询结果的集合。
-
PreparedStatement:比Statement更加安全,支持预编译SQL语句。
-
CallableStatement:用于执行数据库存储过程。
-
Transaction:事务控制,支持提交和回滚。
JDBC架构图
+--------------------------+
| Application |
| (Java Code) |
+--------------------------+
|
v
+--------------------------+
| DriverManager |
| (Manages Drivers) |
+--------------------------+
|
v
+--------------------------+
| Connection |
| (Database Connection) |
+--------------------------+
|
v
+--------------------------+
| Statement/Prepared |
| Statement/Callable |
+--------------------------+
|
v
+--------------------------+
| ResultSet |
| (Query Result) |
+--------------------------+
3. JDBC连接流程
JDBC连接数据库的基本步骤如下:
-
加载数据库驱动 :通过
Class.forName()方法加载数据库驱动。 -
建立连接 :通过
DriverManager.getConnection()方法建立数据库连接。 -
执行SQL语句 :使用
Statement或PreparedStatement执行SQL语句。 -
处理结果集 :使用
ResultSet获取查询结果。 -
关闭连接 :操作完成后,关闭
ResultSet、Statement和Connection。
4. JDBC代码示例
1) 基本的JDBC查询操作
import java.sql.*;
public class JDBCExample {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 加载数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 建立数据库连接
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb", "root", "password");
// 3. 创建Statement对象
stmt = conn.createStatement();
// 4. 执行查询操作
String sql = "SELECT id, name, email FROM users";
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.println("ID: " + id + ", Name: " + name + ", Email: " + email);
}
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
解释:
-
DriverManager.getConnection()用于建立数据库连接。 -
Statement.executeQuery()用于执行查询操作,并返回ResultSet。 -
ResultSet用于处理查询结果。
2) 插入数据
public void insertUser(String name, String email) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 1. 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 建立连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "password");
// 3. 创建PreparedStatement
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
pstmt = conn.prepareStatement(sql);
// 4. 设置参数
pstmt.setString(1, name);
pstmt.setString(2, email);
// 5. 执行插入操作
int rowsAffected = pstmt.executeUpdate();
System.out.println(rowsAffected + " row(s) inserted.");
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
解释:
PreparedStatement用于执行插入、更新等操作,支持参数化查询,避免SQL注入攻击。
3) 事务管理
public void transferMoney(int fromAccount, int toAccount, double amount) {
Connection conn = null;
PreparedStatement pstmt1 = null, pstmt2 = null;
try {
// 1. 加载驱动并建立连接
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "password");
// 2. 开始事务
conn.setAutoCommit(false);
// 3. 执行转账操作
String sql1 = "UPDATE accounts SET balance = balance - ? WHERE account_id = ?";
pstmt1 = conn.prepareStatement(sql1);
pstmt1.setDouble(1, amount);
pstmt1.setInt(2, fromAccount);
pstmt1.executeUpdate();
String sql2 = "UPDATE accounts SET balance = balance + ? WHERE account_id = ?";
pstmt2 = conn.prepareStatement(sql2);
pstmt2.setDouble(1, amount);
pstmt2.setInt(2, toAccount);
pstmt2.executeUpdate();
// 4. 提交事务
conn.commit();
System.out.println("Transfer successful.");
} catch (SQLException | ClassNotFoundException e) {
try {
// 回滚事务
if (conn != null) conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
try {
if (pstmt1 != null) pstmt1.close();
if (pstmt2 != null) pstmt2.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
解释:
-
conn.setAutoCommit(false)禁用自动提交,手动控制事务。 -
conn.commit()提交事务,conn.rollback()回滚事务。
5. JDBC常见问题
-
如何处理数据库连接池?
JDBC连接池用于管理数据库连接,提高数据库连接的重用性和性能。常用的连接池库有 C3P0、HikariCP 和 DBCP。
-
JDBC如何避免SQL注入?
使用
PreparedStatement而不是Statement,因为PreparedStatement通过预编译SQL语句来避免SQL注入。
6. 总结
JDBC是Java开发中与数据库交互的基础,虽然相比于一些高级框架(如Hibernate),JDBC显得更加底层,但它提供了更高的灵活性和控制权。掌握JDBC的基本操作,包括数据库连接、SQL执行、事务管理等,是每个Java开发者的必备技能。
通过本篇文章的示例代码和概念讲解,希望能够帮助你更好地理解JDBC的核心原理与应用。
这篇文章讲解了JDBC的基本使用和一些常见的数据库操作,若你希望看到更深入的JDBC使用或数据库优化技巧,随时可以提问。