JDBC(Java Database Connectivity)是 Java 访问数据库的标准接口,它允许开发者通过统一的 API 连接不同类型的数据库。本文将从基础概念入手,详细讲解 JDBC 的核心功能,并通过实例演示如何在项目中使用。
JDBC 架构分为两层:
核心组件包括:
建立数据库连接的步骤如下:
以下是连接 MySQL 数据库的示例代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcConnectionExample {
public static void main(String[] args) {
// 数据库连接信息
String url = "jdbc:mysql://localhost:3306/mydatabase";
String username = "root";
String password = "password";
// 尝试资源语句自动关闭连接
try (Connection connection = DriverManager.getConnection(url, username, password)) {
System.out.println("数据库连接成功!");
// 后续操作...
} catch (SQLException e) {
System.err.println("连接失败: " + e.getMessage());
e.printStackTrace();
}
}
}
连接 URL 格式说明:
jdbc:mysql://
:MySQL 数据库协议localhost:3306
:数据库服务器地址和端口mydatabase
:要连接的数据库名称PreparedStatement
是防止 SQL 注入的关键工具,它通过预编译 SQL 语句并使用参数占位符来提高安全性和性能。
示例:插入数据
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class PreparedStatementExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydatabase";
String username = "root";
String password = "password";
// SQL 插入语句,使用 ? 作为参数占位符
String sql = "INSERT INTO users (name, age, email) VALUES (?, ?, ?)";
try (Connection conn = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 设置参数值
pstmt.setString(1, "张三");
pstmt.setInt(2, 25);
pstmt.setString(3, "[email protected]");
// 执行更新
int rowsInserted = pstmt.executeUpdate();
if (rowsInserted > 0) {
System.out.println("数据插入成功!");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
防止 SQL 注入对比:
普通 Statement:
// 存在 SQL 注入风险
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
PreparedStatement:
// 安全的参数化查询
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
pstmt.setString(1, username);
pstmt.setString(2, password);
查询操作会返回 ResultSet
对象,它表示查询结果集。处理结果集的基本步骤:
next()
方法移动游标getInt()
、getString()
等方法示例:查询并处理数据
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ResultSetExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydatabase";
String username = "root";
String password = "password";
// 查询语句
String sql = "SELECT id, name, age, email FROM users WHERE age > ?";
try (Connection conn = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 设置查询参数
pstmt.setInt(1, 20);
// 执行查询
ResultSet rs = pstmt.executeQuery();
// 处理结果集
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
String email = rs.getString("email");
System.out.printf("ID: %d, 姓名: %s, 年龄: %d, 邮箱: %s%n", id, name, age, email);
}
// 关闭结果集
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
结果集元数据:
通过 ResultSetMetaData
可以获取结果集的结构信息:
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
System.out.println("列名: " + metaData.getColumnName(i));
System.out.println("类型: " + metaData.getColumnTypeName(i));
}
为避免资源泄漏,建议:
事务处理示例:
try (Connection conn = DriverManager.getConnection(url, username, password)) {
// 关闭自动提交,开启事务
conn.setAutoCommit(false);
try (PreparedStatement pstmt1 = conn.prepareStatement("UPDATE accounts SET balance = balance - ? WHERE id = ?");
PreparedStatement pstmt2 = conn.prepareStatement("UPDATE accounts SET balance = balance + ? WHERE id = ?")) {
// 执行第一个更新
pstmt1.setDouble(1, 100.0);
pstmt1.setInt(2, 1);
pstmt1.executeUpdate();
// 执行第二个更新
pstmt2.setDouble(1, 100.0);
pstmt2.setInt(2, 2);
pstmt2.executeUpdate();
// 提交事务
conn.commit();
} catch (SQLException e) {
// 回滚事务
conn.rollback();
e.printStackTrace();
}
}
JDBC 是 Java 与数据库交互的基础,掌握以下关键点:
通过本文的示例,你可以构建基本的数据库应用程序。在实际开发中,还可以考虑使用数据库连接池(如 HikariCP)和 ORM 框架(如 Hibernate)来简化数据库操作。