JDBC 的编写步骤及原理详解
一、JDBC 简介
JDBC(Java DataBase Connectivity)即 Java 数据库连接,是 Java 语言用于操作数据库的一套 API。它为多种关系数据库提供了统一的访问方式,允许 Java 程序与不同类型的数据库(如 MySQL、Oracle、SQL Server 等)进行连接和交互,实现对数据库的增删改查等操作。
二、JDBC 原理
(一)JDBC 架构
JDBC 采用了两层模型:
- 应用程序层:即我们编写的 Java 程序,通过 JDBC API 来访问数据库。
- 数据库驱动层:由数据库厂商提供的驱动程序,遵循 JDBC 规范,负责与具体的数据库进行通信。不同数据库有各自对应的驱动,如 MySQL 的驱动是
com.mysql.cj.jdbc.Driver
,Oracle 也有其对应的驱动。
(二)核心接口和类
- DriverManager(驱动管理器)
- 注册驱动:它的作用之一是让 JDBC 知道要使用哪个数据库驱动。例如,通过
Class.forName("com.mysql.cj.jdbc.Driver")
加载 MySQL 驱动类,驱动类在加载时会自动将自己注册到DriverManager
中。在早期也可以使用DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver())
来注册,但前者是更常用的方式。 - 获取 Connection:负责获取与数据库的连接。当成功获取到
Connection
对象时,意味着 Java 程序与数据库建立了连接。它会根据传入的数据库 URL、用户名和密码等信息来尝试连接数据库。
- 注册驱动:它的作用之一是让 JDBC 知道要使用哪个数据库驱动。例如,通过
- Connection(连接)
- 代表 Java 程序与数据库之间的连接通道,与数据库的所有通讯都通过这个对象展开。
- 最为重要的一个方法是用来获取
Statement
对象或PreparedStatement
对象,通过这些对象来向数据库发送 SQL 语句。
- Statement(语句)
- 用于向数据库发送 SQL 语句。可以执行不带参数的简单 SQL 语句,即静态 SQL 语句。例如,使用
Statement
执行查询语句:Statement st = conn.createStatement(); ResultSet rs = st.executeQuery("select * from table_name");
。 - 缺点是对于需要频繁执行且只有参数不同的 SQL 语句,性能较差,因为每次都要重新解析 SQL 语句。
- 用于向数据库发送 SQL 语句。可以执行不带参数的简单 SQL 语句,即静态 SQL 语句。例如,使用
- PreparedStatement(预编译语句)
- 是
Statement
的子接口,它可以对 SQL 语句进行预编译,将 SQL 语句模板和参数分开。SQL 语句模板中使用占位符?
来代替实际参数。例如:String sql = "select * from user where name=?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, "zhangsan");
。 - 优势在于提高了性能,因为预编译后的 SQL 语句在数据库端会被缓存,后续执行相同结构的 SQL 语句时,只需传入不同参数即可,无需重新解析 SQL;同时也增强了安全性,防止 SQL 注入攻击,因为参数是经过特殊处理后传入的。
- 是
- ResultSet(结果集)
- 表示数据库执行查询操作后返回的结果集,是一个二维的表格形式,有行有列。
- 提供了一系列方法来操作结果集,如
boolean next()
方法用于将 “行光标” 移动到下一行,并返回移动后的行是否存在;XXX getXXX(int col)
方法用于获取当前行指定列上的值,列数从 1 开始计数 。
三、JDBC 编写步骤
(一)注册驱动
通过Class.forName("数据库驱动类名")
来加载数据库驱动类,使其自动注册到DriverManager
中。例如,对于 MySQL 8.0 及以上版本,使用Class.forName("com.mysql.cj.jdbc.Driver")
;如果是 MySQL 5 及之前版本,则使用com.mysql.jdbc.Driver
。这一步告诉 Java 程序即将要连接的是哪个品牌的数据库。
(二)获取连接
使用DriverManager.getConnection(url, username, password)
方法获取与数据库的连接。其中:
- url:是数据库的统一资源定位符,用于指定要连接的数据库位置和相关信息。格式由三部分组成,以 MySQL 为例,
jdbc:mysql://IP地址:端口号/数据库名
,如jdbc:mysql://localhost:3306/mydb
,表示连接本地 3306 端口上的名为mydb
的数据库。还可以添加一些参数,如jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8
,用于指定字符集等。 - username:登录数据库的用户名。
- password:登录数据库的密码。
(三)获取数据库操作对象
根据不同需求获取Statement
或PreparedStatement
对象:
- 获取 Statement 对象:使用
Connection
对象的createStatement()
方法,如Statement stmt = conn.createStatement();
,适用于执行简单的、不常变动的 SQL 语句。 - 获取 PreparedStatement 对象:使用
Connection
对象的prepareStatement(String sql)
方法,传入 SQL 语句模板,如PreparedStatement pstmt = conn.prepareStatement("select * from user where id = ?");
,适用于需要预编译、动态传入参数的场景。
(四)执行 SQL 语句
- 对于增删改操作:使用
Statement
的executeUpdate(String sql)
方法或PreparedStatement
的executeUpdate()
方法(PreparedStatement
因为已经预编译绑定了 SQL 语句,所以调用时不需要再传入 SQL 语句)。该方法返回一个整数,表示受影响的行数。例如:
java
String sql = "insert into user (name, age) values ('张三', 25)";
int affectedRows = stmt.executeUpdate(sql);
- 对于查询操作:使用
Statement
的executeQuery(String sql)
方法或PreparedStatement
的executeQuery()
方法,返回一个ResultSet
对象。例如:
java
String sql = "select * from user";
ResultSet rs = stmt.executeQuery(sql);
(五)处理查询结果(仅针对查询操作)
当执行查询操作得到ResultSet
后,通过ResultSet
的方法来遍历和获取数据。例如:
java
while (rs.next()) {int id = rs.getInt("id");String name = rs.getString("name");System.out.println("ID: " + id + ", Name: " + name);
}
这里通过next()
方法移动行光标,然后使用getInt
、getString
等方法根据列名或列索引获取对应的值。
(六)释放资源
使用完Connection
、Statement
(或PreparedStatement
)、ResultSet
等资源后,要及时关闭,以释放数据库服务器资源和避免内存泄漏。一般在finally
块中进行关闭操作,如下:
java
finally {if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}
}
以下是一个完整的 JDBC 操作 MySQL 数据库进行查询的示例代码:
java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;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. 获取连接String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8";String username = "root";String password = "123456";conn = DriverManager.getConnection(url, username, password);// 3. 获取数据库操作对象stmt = conn.createStatement();// 4. 执行SQL语句String sql = "select * from user";rs = stmt.executeQuery(sql);// 5. 处理查询结果while (rs.next()) {int id = rs.getInt("id");String name = rs.getString("name");System.out.println("ID: " + id + ", Name: " + name);}} catch (Exception e) {e.printStackTrace();} finally {// 6. 释放资源if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}}
}
通过网盘分享的文件:03_黑马程序员_JDBC_分析jdbc程序的编写步骤和原理.rar
链接: https://pan.baidu.com/s/1R0tf7XlurHOx-SlSq2ySFw