JDBC
7.1 JDBC技术
1. 定义与背景
- 定义:JDBC是由Java编程语言编写的类及接口组成,为程序开发人员提供了一组用于实现对数据库访问的JDBC API,并支持SQL语言。JDBC全称为Java Data Base Connectivity(Java数据库连接),是Sun Microsystems(现为Oracle Corporation)开发的一套数据库访问编程接口。
- 背景:JDBC的出现解决了Java语言在企业级应用中与数据库交互的标准化问题。在JDBC之前,数据库互操作性常常依赖于数据库厂商特定的API或ODBC(Open Database Connectivity)等接口,这些方法存在限制,特别是降低了Java程序的可移植性。JDBC的推出,使得Java程序能够以跨平台、与数据库厂商无关的方式访问数据库。
2. 主要功能与特点
- 主要功能:
- 建立与数据库或其他数据源的连接。
- 向数据库发送SQL语句。
- 处理数据库的返回结果。
- 特点:
- 跨平台性:JDBC编写的数据库应用程序可以在任何支持Java的平台上运行。
- 统一性:为多种关系数据库提供统一访问接口,简化了数据库访问的复杂性。
- 灵活性:支持多种类型的SQL语句,包括查询、更新、删除等。
- 安全性:通过JDBC进行数据库操作时,可以利用Java的安全特性来保护数据。
7.2 JDBC中常用类和接口
1. DriverManager类
- 作用:用于管理JDBC驱动程序,是JDBC的管理层,作用于用户和驱动程序之间。通过getConnection()方法来建立数据库连接,否则会抛出异常。
- 特点:所有方法都是静态的,调用时无需实例化,通过类名就可以直接调用。
- 常用方法:getConnection(String url, String user, String password),通过数据库的URL、用户名和密码返回数据库的Connection对象。
2. Driver接口
- 作用:定义数据库驱动应该具备的一些能力,比如与数据库建立连接的方法。所有支持Java语言连接的数据库都实现了该接口,实现该接口的类我们称之为数据库驱动类。
- 特点:在程序中要连接数据库,必须先通过JDK的反射机制加载数据库驱动类,将其实例化。
3. Connection接口
- 作用:表示与数据库的连接(会话)对象,可以通过该对象执行SQL语句并返回结果。
- 常用方法:
- createStatement():创建向数据库发送SQL的Statement接口类型的对象。
- prepareStatement(String sql):创建向数据库发送预编译SQL的PreparedStatement接口类型的对象。
- prepareCall(String sql):创建执行存储过程的CallableStatement接口类型的对象。
- setAutoCommit(boolean autoCommit):设置事务是否自动提交。
- commit():在连接上手动提交事务。
- rollback():在连接上回滚事务。
4. Statement接口
- 作用:用于执行静态SQL语句并返回它所生成结果的对象。
- 常用方法:
- executeQuery(String sql):执行SQL查询语句,返回ResultSet对象。
- executeUpdate(String sql):执行SQL更新语句(如INSERT、UPDATE、DELETE),返回受影响的行数。
- execute(String sql):执行SQL语句,返回是否有结果集。
5. PreparedStatement接口
- 作用:继承自Statement接口,用于执行含有一个或多个参数的SQL语句。PreparedStatement对象比Statement对象的效率要更高,并且可以防止SQL注入,所以更常用。
- 常用方法:
- executeQuery():执行当前的查询,返回一个结果集对象。
- executeUpdate():运行INSERT/UPDATE/DELETE操作,返回更新的行数。
- setXXX(int parameterIndex, XXX x):设置SQL语句中指定位置的参数值,其中XXX表示参数的数据类型。
6. ResultSet接口
- 作用:提供检索数据库表中数据的接口,类似于一个临时表,用来暂存数据库查询操作所获取的结果集。
- 常用方法:
- next():将光标移动到下一行。
- getString(int columnIndex)、getString(String columnName):获取当前行指定列(通过索引或列名)的字符串值。
- getInt(int columnIndex)、getInt(String columnName):获取当前行指定列的整数值。
- getDate(int columnIndex)、getDate(String columnName):获取当前行指定列的日期值。
- getObject(int columnIndex)、getObject(String columnName):获取当前行指定列的任意类型值。
7. CallableStatement接口
- 作用:继承自PreparedStatement接口,用于调用数据库的存储过程。
- 特点:可以调用数据库中的存储过程,并支持对存储过程的输入输出参数进行操作。
7.3 连接数据库
JDBC(Java Database Connectivity)连接数据库的过程涉及几个关键步骤,包括加载数据库驱动、建立数据库连接、执行SQL语句以及处理结果。以下是一个简单的JDBC连接数据库的过程示例,以连接MySQL数据库为例:
1. 加载数据库驱动
首先,你需要将数据库驱动(如MySQL的JDBC驱动mysql-connector-java-x.x.xx.jar)添加到你的项目依赖中。如果你使用的是Maven或Gradle这样的构建工具,你可以通过在pom.xml或build.gradle文件中添加相应的依赖来自动管理。 对于手动管理依赖,你需要将JDBC驱动的JAR文件放在项目的类路径(classpath)中。 在Java代码中,你可以使用Class.forName()方法来加载数据库驱动,但自从JDBC 4.0开始,如果你的JDBC驱动遵循了SPI(Service Provider Interface)机制,这一步通常是可选的,因为JDBC 4.0及以上版本的DriverManager会自动加载实现了java.sql.Driver接口的驱动。不过,为了兼容性或明确性,有时仍然会显式地加载驱动。
try {
Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL JDBC 驱动
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2. 建立数据库连接
使用DriverManager.getConnection()方法来建立与数据库的连接。你需要提供数据库的URL、用户名和密码作为参数。
String url = "jdbc:mysql://localhost:3306/yourDatabaseName?serverTimezone=UTC";
String user = "yourUsername";
String password = "yourPassword";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
// 现在你可以使用conn对象来执行SQL语句了
} catch (SQLException e) {
e.printStackTrace();
}
注意:在上面的URL中,jdbc:mysql://localhost:3306/yourDatabaseName是标准的MySQL JDBC URL格式,其中localhost是数据库服务器的地址,3306是MySQL的默认端口号,yourDatabaseName是你的数据库名。?serverTimezone=UTC是一个连接属性,用于指定服务器时区,因为JDBC驱动和MySQL服务器之间的时区差异可能会导致问题。
3. 执行SQL语句
一旦你有了Connection对象,你就可以使用它来创建Statement、PreparedStatement或CallableStatement对象,并执行SQL语句了。
Statement stmt = null;
try {
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM yourTableName");
while (rs.next()) {
// 处理结果集
int id = rs.getInt("id");
String name = rs.getString("name");
// ...
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
4. 处理结果
使用ResultSet对象来遍历和处理SQL查询返回的结果集。
5. 关闭资源
最后,不要忘记关闭Statement、ResultSet和Connection对象,以释放数据库资源。这通常是在finally块中完成的,以确保无论是否发生异常,资源都能被正确关闭。 请注意,上述代码示例仅用于演示目的,并未包含所有可能的错误处理和资源管理最佳实践。在实际应用中,你可能需要更细致地处理这些方面。
7.4 Statement接口
Statement 接口在 JDBC(Java Database Connectivity)中扮演着执行静态 SQL 语句并返回结果的重要角色。它是 java.sql 包的一部分,提供了一种与数据库进行交互的方式,允许你执行 SQL 语句(如 SELECT、INSERT、UPDATE、DELETE 等)并处理结果。
主要功能
- 执行 SQL 语句:Statement 接口提供了几种方法来执行 SQL 语句,包括 executeQuery(String sql)(用于执行返回结果集的查询,如 SELECT 语句),executeUpdate(String sql)(用于执行不返回结果集的更新语句,如 INSERT、UPDATE、DELETE),以及 execute(String sql)(用于执行任何类型的 SQL 语句,并返回一个布尔值以指示返回的结果是一个结果集还是一个更新计数)。
- 获取结果:如果 SQL 语句是一个查询(SELECT),则可以通过 executeQuery 方法返回的 ResultSet 对象来获取查询结果。ResultSet 对象类似于一个临时表,包含了查询结果的所有行和列。
- 处理更新:如果 SQL 语句是一个更新(INSERT、UPDATE、DELETE),则可以通过 executeUpdate 方法返回的整数来获取受影响的行数。
常用方法
- executeQuery(String sql): 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。
- executeUpdate(String sql): 执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。
- execute(String sql): 执行给定的 SQL 语句,该语句可能返回多个结果。
- getResultSet(): 检索由 execute 方法执行后返回的第一个 ResultSet 对象。
- getUpdateCount(): 检索由 execute 方法执行后作为更新计数的第一个整数。
- getMoreResults(): 将 Statement 对象移动到下一个结果,如果有的话,并且返回 true。
- close(): 立即释放此 Statement 对象的数据库和 JDBC 资源,而不是等待它们被自动释放。
注意事项
- 使用 Statement 时,应该注意 SQL 注入的风险,因为它直接将 SQL 语句(包括可能来自不可信源的参数)发送到数据库。为了降低这种风险,建议使用 PreparedStatement。
- 始终确保在不再需要时关闭 Statement 对象,以释放数据库资源。这通常是在 finally 块中完成的。
- 尽管 Statement 接口提供了基本的 SQL 执行功能,但在处理复杂查询或需要性能优化的场景时,PreparedStatement 和 CallableStatement 可能是更好的选择。
7.5 ResultSet接口
ResultSet 接口是 Java JDBC(Java Database Connectivity)API 的一部分,它表示数据库查询操作的结果集。通过执行 SQL 查询语句,可以得到一个 ResultSet 对象,该对象包含了查询结果的所有行和列。以下是对 ResultSet 接口的详细解释:
基本概述
- 接口定义:ResultSet 接口定义在 java.sql 包中,是 JDBC API 的核心组件之一。
- 作用:表示数据库查询的结果集,提供了一系列方法来遍历和访问结果集中的数据。
主要功能
- 遍历结果集:
- ResultSet 对象具有一个指向当前数据行的光标(或指针)。最初,光标被置于第一行之前。
- 使用 next() 方法将光标移动到下一行。如果结果集中还有行,则该方法返回 true;否则返回 false。因此,可以在 while 循环中使用 next() 方法来迭代结果集。
- 访问数据:
- 提供了一系列获取方法(如 getString(), getInt(), getBoolean() 等),用于从当前行中检索列值。可以使用列的索引编号(从 1 开始)或列的名称来检索值。
- 一般情况下,使用列索引较为高效。为了获得最大的可移植性,应该按从左到右的顺序读取每行中的结果集列,并且每列只能读取一次。
- 更新和插入数据(在可更新的 ResultSet 中):
- 从 JDBC 2.0 API 开始,ResultSet 接口添加了一组更新方法,允许在可更新的 ResultSet 对象中更新当前行的列值。
- 还可以将光标移动到特殊的插入行,并构建要插入的行,然后将其插入到底层数据库中。
注意事项
- 默认的 ResultSet 对象是不可更新的,并且仅有一个向前移动的光标。因此,只能按从第一行到最后一行的顺序迭代它一次。
- 可以生成可滚动和/或可更新的 ResultSet 对象,这需要在创建 Statement 对象时指定相应的类型(如 TYPE_SCROLL_INSENSITIVE)和并发性(如 CONCUR_UPDATABLE)。
- 当生成 ResultSet 对象的 Statement 对象关闭、重新执行或用来从多个结果的序列检索下一个结果时,ResultSet 对象会自动关闭。
- ResultSet 对象的列的编号、类型和属性可以通过调用 ResultSet.getMetaData() 方法获取的 ResultSetMetaData 对象来提供。
示例代码
以下是一个简单的示例,演示了如何使用 ResultSet 遍历查询结果:
Statement stmt = conn.createStatement(); // conn 是有效的 Connection 对象
ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM users");
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age);
}
rs.close();
stmt.close();
请注意,上述代码中的 conn 是指已经建立好的数据库连接对象。在实际应用中,还需要处理可能的 SQLException 异常,并在使用完毕后关闭 ResultSet 和 Statement 对象以释放资源。
7.6 PreparedStatement接口
PreparedStatement 接口是 JDBC(Java Database Connectivity)API 中的一个重要接口,它继承自 Statement 接口,并提供了执行预编译 SQL 语句的能力。以下是关于 PreparedStatement 接口的详细解释:
1. 基本概念
- 定义:PreparedStatement 接口表示一条预编译的 SQL 语句,它允许你使用占位符(通常是问号 ?)来代表 SQL 语句中的参数,并在执行前为这些参数设置具体的值。
- 作用:PreparedStatement 提供了更高效、更安全的方式来执行 SQL 语句,特别是在需要多次执行相似 SQL 语句的情况下。
2. 主要功能
- 预编译 SQL 语句:SQL 语句在执行前会被编译成数据库可执行的格式,减少了编译的开销,提高了执行效率。
- 防止 SQL 注入:通过参数化查询,PreparedStatement 可以有效防止 SQL 注入攻击,因为它不会将参数值直接拼接到 SQL 语句中。
- 设置参数:提供了 setXxx() 方法(如 setString(), setInt() 等)来设置 SQL 语句中的参数值,其中 Xxx 表示参数的数据类型。
- 执行 SQL 语句:提供了 executeQuery() 方法来执行查询操作,并返回 ResultSet 对象;提供了 executeUpdate() 方法来执行更新操作(如 INSERT、UPDATE、DELETE),并返回受影响的行数。
- 批处理:支持批处理操作,可以一次性执行多个 SQL 语句,提高了数据操作的效率。
3. 使用步骤
- 获取 Connection 对象:首先需要获取到数据库的连接对象。
- 编写 SQL 语句:编写包含占位符的 SQL 语句。
- 创建 PreparedStatement 对象:通过 Connection 对象的 prepareStatement(String sql) 方法传入 SQL 语句,创建 PreparedStatement 对象。
- 设置参数:使用 setXxx() 方法为 SQL 语句中的占位符设置具体的参数值。
- 执行 SQL 语句:根据需要执行查询操作(executeQuery())或更新操作(executeUpdate())。
- 处理结果:对于查询操作,处理返回的 ResultSet 对象;对于更新操作,处理返回的受影响行数。
- 关闭资源:关闭 ResultSet、PreparedStatement 和 Connection 对象,释放数据库资源。
4. 示例代码
以下是一个使用 PreparedStatement 执行查询操作的示例代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class PreparedStatementExample {
public static void main(String[] args) {
// 数据库连接信息(这里仅作示例,请根据实际情况修改)
String url = "jdbc:mysql://localhost:3306/yourdatabase";
String user = "yourusername";
String password = "yourpassword";
// 加载数据库驱动(如果 JDBC 4.0 以上版本,且驱动已包含在 classpath 中,则可以省略)
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 获取数据库连接
try (Connection connection = DriverManager.getConnection(url, user, password)) {
// 编写 SQL 语句
String sql = "SELECT * FROM users WHERE username = ?";
// 创建 PreparedStatement 对象
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
// 设置参数
preparedStatement.setString(1, "exampleUser");
// 执行查询操作
try (ResultSet resultSet = preparedStatement.executeQuery()) {
// 处理查询结果
while (resultSet.next()) {
// 假设用户表中有 id 和 name 两个字段
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
请注意,上述代码中的数据库连接信息(URL、用户名、密码)和 SQL 语句都是示例,你需要根据实际情况进行修改。同时,为了简化示例,这里省略了异常处理和资源关闭的详细代码,但在实际开发中,你应该始终确保妥善处理异常并正确关闭数据库资源。
7.7 CallableStatement接口
CallableStatement 接口是 JDBC(Java Database Connectivity)API 中的一个重要接口,它继承自 PreparedStatement 接口,并提供了执行数据库中存储过程的能力。以下是关于 CallableStatement 接口的详细解释:
1. 基本概念
- 定义:CallableStatement 接口用于执行数据库中已存储的过程(Stored Procedure)。它允许你调用数据库中定义的存储过程,并可以接收存储过程的返回值以及输出参数。
- 作用:通过 CallableStatement,Java 应用程序可以以标准的方式调用数据库中的存储过程,从而执行复杂的数据库操作,如事务处理、复杂查询等。
2. 主要功能
- 调用存储过程:CallableStatement 提供了执行存储过程的能力,可以传递输入参数给存储过程,并接收存储过程的返回值和输出参数。
- 处理 OUT 参数:对于存储过程的输出参数(OUT 参数),CallableStatement 提供了 registerOutParameter() 方法来注册这些参数的类型,并在执行后通过 getXXX() 方法检索它们的值。
- 处理 ResultSet:如果存储过程返回了一个或多个 ResultSet 对象,CallableStatement 也提供了相应的方法来检索这些结果集。
3. 使用步骤
- 获取 Connection 对象:首先需要获取到数据库的连接对象。
- 创建 CallableStatement 对象:通过 Connection 对象的 prepareCall(String sql) 方法传入调用存储过程的 SQL 语句(使用 JDBC 的存储过程转义语法),创建 CallableStatement 对象。
- 注册 OUT 参数(如果需要):如果存储过程有 OUT 参数,使用 registerOutParameter() 方法注册这些参数的类型。
- 设置 IN 参数:使用 setXxx() 方法为存储过程的输入参数设置值。
- 执行存储过程:调用 execute() 方法执行存储过程。
- 处理结果:根据需要处理返回的 ResultSet 对象、更新计数(如果有)以及 OUT 参数的值。
- 关闭资源:关闭 ResultSet、CallableStatement 和 Connection 对象,释放数据库资源。
4. 示例代码
以下是一个使用 CallableStatement 调用存储过程的示例代码(假设存储过程名为 getTestData,有两个输入参数,无返回值):
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class CallableStatementExample {
public static void main(String[] args) {
// 数据库连接信息(这里仅作示例,请根据实际情况修改)
String url = "jdbc:mysql://localhost:3306/yourdatabase";
String user = "yourusername";
String password = "yourpassword";
// 加载数据库驱动(如果 JDBC 4.0 以上版本,且驱动已包含在 classpath 中,则可以省略)
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 获取数据库连接
try (Connection connection = DriverManager.getConnection(url, user, password)) {
// 创建 CallableStatement 对象(假设存储过程有两个输入参数)
String sql = "{call getTestData(?, ?)}";
try (CallableStatement callableStatement = connection.prepareCall(sql)) {
// 设置输入参数
callableStatement.setInt(1, 10); // 假设第一个参数是整数类型
callableStatement.setString(2, "test"); // 假设第二个参数是字符串类型
// 执行存储过程(这里假设存储过程没有返回值)
callableStatement.execute();
// 注意:如果存储过程有返回值或输出参数,需要在这里处理它们
// ...(其他处理逻辑)
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
请注意,上述代码中的数据库连接信息(URL、用户名、密码)和 SQL 语句都是示例,你需要根据实际情况进行修改。同时,示例中的存储过程 getTestData 也是假设存在的,你需要将其替换为实际数据库中的存储过程名称,并根据存储过程的实际参数情况调整代码。 此外,对于带有 OUT 参数的存储过程调用,你需要在执行存储过程之前使用 registerOutParameter() 方法注册 OUT 参数的类型,并在执行后通过相应的 getXXX() 方法检索它们的值。
7.8 游动查询
游动查询,在数据库操作中,通常指的是在结果集中前后移动或访问结果集中特定记录的能力。这种查询方式在处理大量数据时特别有用,尤其是在需要非顺序访问结果集的情况下。以下是对游动查询的详细解释:
1、游动查询的基本概念
游动查询允许用户在结果集中自由移动游标,从而可以访问结果集中的任意行。这与传统的顺序查询(即只能从头到尾依次访问结果集)不同,提供了更高的灵活性和便利性。
2、实现游动查询的方法
在JDBC(Java Database Connectivity)中,实现游动查询通常需要使用支持可滚动结果集的Statement对象。具体步骤如下:
- 创建支持可滚动的Statement对象: 通过调用Connection对象的createStatement(int resultSetType, int resultSetConcurrency)方法,并传入适当的参数来创建支持可滚动的Statement对象。其中,resultSetType参数应设置为ResultSet.TYPE_SCROLL_INSENSITIVE或ResultSet.TYPE_SCROLL_SENSITIVE,以支持结果集的滚动。
- 执行查询并获取ResultSet对象: 使用上一步创建的Statement对象执行SQL查询,并获取ResultSet对象。这个ResultSet对象将支持滚动操作。
- 使用滚动方法访问结果集: ResultSet对象提供了多种方法来滚动结果集,包括next()、previous()、first()、last()、absolute(int row)、beforeFirst()和afterLast()等。通过这些方法,可以在结果集中前后移动游标,从而访问任意行。
3、游动查询的应用场景
游动查询在多种场景下都非常有用,包括但不限于:
- 分页显示:在Web应用中,经常需要将大量数据分页显示给用户。通过游动查询,可以轻松地跳转到结果集的任意一页,而无需重新执行查询。
- 随机访问:在处理复杂的数据报表或分析时,可能需要随机访问结果集中的特定记录。游动查询提供了这种能力。
- 数据审核:在审核大量数据时,用户可能需要反复查看和比较结果集中的不同记录。游动查询使得这种操作变得更加方便。
4、注意事项
- 性能考虑:虽然游动查询提供了更高的灵活性,但在处理大量数据时可能会对性能产生影响。因此,在设计数据库查询时,需要权衡灵活性和性能之间的平衡。
- 资源消耗:可滚动的ResultSet对象可能会消耗更多的内存和数据库资源。因此,在使用时需要注意资源的合理分配和释放。
- 兼容性:不同的数据库管理系统(DBMS)对可滚动结果集的支持程度可能不同。因此,在开发跨数据库的应用程序时,需要注意兼容性问题。
综上所述,游动查询是数据库操作中一种非常有用的技术,它提供了在结果集中自由移动游标的能力,从而可以方便地访问和处理大量数据。然而,在使用时需要注意性能、资源消耗和兼容性等问题。
7.9 JDBC增删改查实践
关于“JDBC增删改查实践”的探讨,我们可以从以下几个方面进行详细说明:
一、JDBC基本概念
JDBC(Java Database Connectivity)是一套面向对象的应用程序接口,它制定了统一的访问各类关系数据库的标准接口,为各个数据库厂商(如MySQL、Oracle等)提供了标准接口的实现。通过使用JDBC技术,开发人员可以用纯Java语言和标准的SQL语句编写完整的数据库应用程序,并且真正实现了软件的跨平台性。
二、JDBC增删改查实践步骤
1. 搭建JDBC开发环境
- 导入JDBC驱动:将数据库(如MySQL)的JDBC驱动jar包添加到项目的classpath中。这通常涉及到将jar包复制到项目的lib目录下,并在IDE中配置库依赖。
- 注册加载Driver:在代码中通过Class.forName("com.mysql.cj.jdbc.Driver");加载数据库驱动。注意,从JDBC 4.0开始,显式加载驱动类的步骤可以省略,因为JDBC服务提供者会自动被加载。
2. 创建数据库连接(Connection)
使用DriverManager.getConnection(String url, String user, String password)方法建立与数据库的连接。其中,url是数据库的地址,user和password分别是数据库的用户名和密码。
3. 创建语句对象(Statement或PreparedStatement)
- Statement:用于执行不带参数的简单SQL语句。
- PreparedStatement:用于执行带或不带参数的SQL语句,SQL语句会预编译在数据库系统,执行速度通常快于Statement对象。
4. 执行SQL语句
- 查询(SELECT):使用executeQuery()方法执行查询操作,并返回ResultSet对象,用于遍历查询结果。
- 增删改(INSERT、UPDATE、DELETE):使用executeUpdate()方法执行增删改操作,并返回受影响的行数。
5. 处理结果(查询操作特有)
对于查询操作,需要遍历ResultSet对象来获取查询结果。通常使用while(rs.next())循环来逐行处理结果集。
6. 释放资源
最后,需要释放ResultSet、Statement和Connection对象,以避免资源泄露。释放原则是先开的后关,后开的先关。
三、JDBC增删改查实践示例
示例1:增加数据
String sql = "INSERT INTO user(id, name, password, email) VALUES(?, ?, ?, ?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 1);
ps.setString(2, "张三");
ps.setString(3, "password123");
ps.setString(4, "zhangsan@example.com");
int affectedRows = ps.executeUpdate();
if (affectedRows > 0) {
System.out.println("数据添加成功");
}
ps.close();
conn.close();
示例2:删除数据
String sql = "DELETE FROM user WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 1);
int affectedRows = ps.executeUpdate();
if (affectedRows > 0) {
System.out.println("数据删除成功");
}
ps.close();
conn.close();
示例3:修改数据
String sql = "UPDATE user SET name = ?, email = ? WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "李四");
ps.setString(2, "lisi@example.com");
ps.setInt(3, 1);
int affectedRows = ps.executeUpdate();
if (affectedRows > 0) {
System.out.println("数据修改成功");
}
ps.close();
conn.close();
示例4:查询数据
String sql = "SELECT * FROM user WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 1);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
System.out.println("ID: " + rs.getInt("id"));
System.out.println("Name: " + rs.getString("name"));
// ... 其他字段
}
rs.close();
ps.close();
conn.close();
四、注意事项
- 在进行数据库操作时,要注意异常处理,确保数据库连接等资源得到正确释放。
- 使用PreparedStatement可以提高安全性,防止SQL注入攻击。