一、简介
Java Database Connectivity(JDBC)是Java应用程序与关系数据库进行交互的一种API。它提供了一组用于访问和操作数据库的标准接口,使开发人员能够使用Java代码执行数据库操作,如查询、插入、更新和删除等。
二、JDBC架构
JDBC由两部分组成:
- JDBC API:由Java SE平台提供的接口和类集合,用于定义与数据库交互的标准。
- JDBC Driver API:由数据库供应商提供的具体实现,用于实际连接和操作数据库。
三、JDBC的核心组件
- DriverManager:管理一组数据库驱动程序的基本服务。
- Connection:表示与特定数据库的连接。
- Statement:用于执行SQL语句的对象,分为
Statement
、PreparedStatement
、CallableStatement
。 - ResultSet:保存由
Statement
对象执行SQL查询返回的结果集。 - SQLException:处理数据库访问出错或其他错误的异常。
四、使用JDBC的步骤
- 加载驱动程序
- 建立数据库连接
- 创建SQL语句
- 执行SQL语句
- 处理结果集
- 关闭连接
五、具体实现
1. 加载驱动程序
在JDBC 4.0之后,驱动程序通常会自动加载,但为了兼容性,手动加载仍然常见。
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2. 建立数据库连接
使用DriverManager
获取数据库连接。
String url = "jdbc:mysql://localhost:3306/mydatabase";
String user = "root";
String password = "password";
Connection connection = null;
try {
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
3. 创建SQL语句
使用Statement
或PreparedStatement
对象创建SQL语句。
Statement statement = connection.createStatement();
String sql = "SELECT * FROM users";
对于参数化查询,使用PreparedStatement
。
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1);
4. 执行SQL语句
根据SQL语句的类型,使用executeQuery
或executeUpdate
方法执行。
查询操作:
ResultSet resultSet = statement.executeQuery(sql);
更新操作:
String updateSql = "UPDATE users SET name = 'John' WHERE id = 1";
int rowsAffected = statement.executeUpdate(updateSql);
5. 处理结果集
ResultSet
对象包含查询结果,可以通过next
方法迭代访问。
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
6. 关闭连接
为了防止资源泄露,必须关闭数据库连接、语句和结果集。
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
六、示例代码
以下是一个完整的JDBC示例程序,展示了如何连接到MySQL数据库,执行查询并处理结果集。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydatabase";
String user = "root";
String password = "password";
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// 加载驱动程序
Class.forName("com.mysql.cj.jdbc.Driver");
// 建立连接
connection = DriverManager.getConnection(url, user, password);
// 创建语句
statement = connection.createStatement();
String sql = "SELECT * FROM users";
// 执行查询
resultSet = statement.executeQuery(sql);
// 处理结果集
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
七、使用PreparedStatement
防止SQL注入
与Statement
相比,PreparedStatement
可以有效防止SQL注入。
String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
八、事务处理
JDBC默认是自动提交模式。可以通过关闭自动提交模式来手动管理事务。
try {
connection.setAutoCommit(false);
// 执行多个更新操作
statement.executeUpdate("INSERT INTO users (name) VALUES ('Alice')");
statement.executeUpdate("INSERT INTO users (name) VALUES ('Bob')");
// 提交事务
connection.commit();
} catch (SQLException e) {
try {
// 回滚事务
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
try {
connection.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
}
九、使用连接池
为了提高性能,减少连接的频繁创建和销毁,推荐使用连接池。常用的连接池实现有Apache DBCP、C3P0和HikariCP。
以下是使用HikariCP的示例:
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class HikariCPDemo {
public static void main(String[] args) {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");
config.setUsername("root");
config.setPassword("password");
DataSource dataSource = new HikariDataSource(config);
try (Connection connection = dataSource.getConnection()) {
String sql = "SELECT * FROM users";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
JDBC是Java与数据库交互的重要工具,掌握其使用方法对于开发高效、可靠的Java应用程序至关重要。通过学习JDBC的基本概念、核心组件和使用步骤,结合具体的代码示例,可以更好地理解和应用JDBC,提升数据库编程能力。
掌握事务处理和连接池的使用可以进一步提高应用程序的性能和稳定性。在实际项目中,通常会结合ORM框架(如Hibernate)来简化数据库操作,但JDBC的基本知识仍是必备的基础技能。
黑马程序员免费预约咨询