目录
- 环境准备
- 安装 Oracle 数据库
- 下载 JDBC 驱动 (OJDBC)
- 配置 Java 开发环境
- 核心步骤
- 添加 JDBC 驱动到项目
- 编写 Java 连接代码
- 完整代码示例
- 基础版(不推荐用于生产)
- 推荐版(使用
try-with-resources) - DML 操作示例(增删改)
- 最佳实践
- 使用连接池
- 加载驱动的方式
- 使用
PreparedStatement
- 常见问题与解决方案
ClassNotFoundExceptionSQLException: No suitable driver foundIO Error: The Network Adapter could not establish the connectionORA-01017: invalid username/password; logon denied
环境准备
在开始编码之前,请确保您已经准备好以下环境:

a. 安装 Oracle 数据库
您需要有一个可运行的 Oracle 数据库实例(如 Oracle Express Edition - XE),并知道以下连接信息:
- 主机名: 通常是
localhost - 端口: Oracle 的默认端口是
1521 - 服务名/SID: 这是数据库的唯一标识,您可以使用 SQL*Plus 或 Oracle Enterprise Manager 查询,XE 版本的服务名通常是
XE。 - 用户名: 如
system - 密码: 您为该用户设置的密码
b. 下载 JDBC 驱动
JDBC 驱动是 Java 程序与 Oracle 数据库通信的桥梁,Oracle 官方称之为 "OJDBC"。
- 访问 Oracle 官方下载页面:Oracle JDBC/ODBC Drivers
- 根据您的 Oracle 数据库版本和 Java 版本选择合适的驱动,对于 Oracle 19c 数据库,您可以选择 ojdbc8.jar(适用于 Java 8)或 ojdbc10.jar(适用于 Java 10 及以上)。
- 下载
.jar文件并记住它的存放位置。
c. 配置 Java 开发环境
确保您的系统已安装 JDK 并配置好了 JAVA_HOME 和 PATH 环境变量,并且可以使用 java 和 javac 命令。
核心步骤
a. 添加 JDBC 驱动到项目
您需要将下载的 OJDBC JAR 文件添加到您的 Java 项目的类路径中,根据您使用的开发工具,方法不同:

-
使用 IDE (如 IntelliJ IDEA 或 Eclipse):
- 右键点击您的项目。
- 选择 "Open Module Settings" (IntelliJ) 或 "Build Path" -> "Configure Build Path" (Eclipse)。
- 在 "Libraries" 或 "Modules" -> "Dependencies" 选项卡中,点击 "Add" 或 "Add External JARs..."。
- 选择您下载的
ojdbcX.jar文件。
-
使用命令行 (Maven): 这是最推荐的方式,在您的
pom.xml文件中添加以下依赖:<dependency> <groupId>com.oracle.database.jdbc</groupId> <artifactId>ojdbc8</artifactId> <version>19.3.0.0</version> <!-- 请使用您下载的驱动版本 --> </dependency>Maven 会自动下载并管理依赖。
-
使用命令行 (手动编译): 如果您不使用构建工具,编译和运行时需要手动指定 JAR 路径。
(图片来源网络,侵删)# 编译 javac -cp ".;C:\path\to\your\ojdbc8.jar" YourJavaFile.java # 运行 (Windows) java -cp ".;C:\path\to\your\ojdbc8.jar" YourJavaFile # 运行 (Linux/macOS) java -cp ".:/path/to/your/ojdbc8.jar" YourJavaFile
注意:类路径分隔符在 Windows 是 ,在 Linux/macOS 是 。
b. 编写 Java 连接代码
连接 Oracle 数据库主要涉及以下几个步骤:
- 加载驱动: 使用
Class.forName()加载 Oracle 的 JDBC 驱动类。 - 获取连接: 使用
DriverManager.getConnection()方法,提供数据库 URL、用户名和密码来创建一个Connection对象。 - 创建语句: 通过
Connection对象创建Statement或PreparedStatement来执行 SQL。 - 执行查询: 使用
executeQuery()执行查询,返回ResultSet。 - 处理结果: 遍历
ResultSet读取数据。 - 关闭资源: 非常重要! 按照从后到前的顺序关闭
ResultSet、Statement和Connection,以释放数据库资源。
完整代码示例
假设您的数据库信息如下:
- URL:
jdbc:oracle:thin:@localhost:1521:XE - 用户名:
system - 密码:
your_password
a. 基础版(不推荐,资源管理繁琐)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
public class OracleJDBCBasicExample {
// 数据库连接信息
static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:XE";
static final String USER = "system";
static final String PASS = "your_password";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 加载 JDBC 驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
// 2. 获取数据库连接
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 3. 创建 Statement 对象
System.out.println("Creating statement...");
stmt = conn.createStatement();
// 4. 执行查询
String sql = "SELECT id, name, email FROM employees";
rs = stmt.executeQuery(sql);
// 5. 处理结果集
System.out.println("\n--- Employee List ---");
while (rs.next()) {
// 通过列名获取数据,更安全
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
// 输出数据
System.out.print("ID: " + id);
System.out.print(", Name: " + name);
System.out.println(", Email: " + email);
}
} catch (ClassNotFoundException e) {
System.err.println("Oracle JDBC Driver not found.");
e.printStackTrace();
} catch (SQLException e) {
System.err.println("Database connection or query failed.");
e.printStackTrace();
} finally {
// 6. 关闭资源 (非常重要!)
System.out.println("\nClosing resources...");
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("Resources closed.");
}
}
}
b. 推荐版(使用 try-with-resources)
Java 7 引入了 try-with-resources 语句,它可以自动实现 AutoCloseable 接口的资源(如 Connection, Statement, ResultSet)的关闭,使代码更简洁、更安全。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
public class OracleJDBCRecommendedExample {
static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:XE";
static final String USER = "system";
static final String PASS = "your_password";
public static void main(String[] args) {
// try-with-resources 会自动关闭 Connection, Statement, 和 ResultSet
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name, email FROM employees")) {
System.out.println("Connected to database successfully.");
System.out.println("\n--- Employee List ---");
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
System.out.printf("ID: %d, Name: %s, Email: %s%n", id, name, email);
}
} catch (SQLException e) {
System.err.println("Database error occurred.");
e.printStackTrace();
}
System.out.println("\nConnection closed automatically.");
}
}
c. DML 操作示例(增删改)
对于 INSERT, UPDATE, DELETE 操作,使用 executeUpdate() 方法,它返回一个整数,表示受影响的行数。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class OracleJDBCDMLOracleExample {
static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:XE";
static final String USER = "system";
static final String PASS = "your_password";
public static void main(String[] args) {
// 使用 try-with-resources 确保 Connection 和 PreparedStatement 被关闭
String insertSql = "INSERT INTO employees (id, name, email) VALUES (?, ?, ?)";
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
// 设置参数 (索引从 1 开始)
pstmt.setInt(1, 101);
pstmt.setString(2, "Alice Johnson");
pstmt.setString(3, "alice.j@example.com");
// 执行插入
int affectedRows = pstmt.executeUpdate();
System.out.println(affectedRows + " row(s) inserted.");
// 更新操作示例
String updateSql = "UPDATE employees SET name = ? WHERE id = ?";
try (PreparedStatement pstmtUpdate = conn.prepareStatement(updateSql)) {
pstmtUpdate.setString(1, "Alice Smith");
pstmtUpdate.setInt(2, 101);
int updatedRows = pstmtUpdate.executeUpdate();
System.out.println(updatedRows + " row(s) updated.");
}
} catch (SQLException e) {
System.err.println("DML operation failed.");
e.printStackTrace();
}
}
}
注意: 在上面的 DML 示例中,我们使用了 PreparedStatement,这是强烈推荐的做法,可以防止 SQL 注入攻击,并且对于需要多次执行的 SQL(参数不同)性能更好。
最佳实践
-
使用连接池: 在生产环境中,绝对不要每次操作都创建和销毁连接,这会带来巨大的性能开销,应该使用连接池(如 HikariCP, DBCP, C3P0)来管理数据库连接。
- HikariCP 是目前性能最好的连接池。
- Spring Boot 等框架已经内置了对 HikariCP 的完美支持。
// HikariCP 简单示例 HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:XE"); config.setUsername("system"); config.setPassword("your_password"); config.setMaximumPoolSize(10); try (HikariDataSource ds = new HikariDataSource(config); Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM employees")) { // ... 使用连接进行操作 ... } catch (SQLException e) { e.printStackTrace(); } -
加载驱动的方式: 在现代 JDBC 驱动(从 JDBC 4.0 开始)中,加载驱动是可选的,驱动程序管理器会自动在类路径中查找可用的驱动。
Class.forName("oracle.jdbc.driver.OracleDriver")这一行代码在现代 Java 应用中通常可以省略。 -
使用
PreparedStatement: 如前所述,始终使用PreparedStatement来执行 SQL,特别是当 SQL 包含来自用户输入的参数时,这是防止 SQL 注入攻击的黄金法则。
常见问题与解决方案
-
ClassNotFoundException: oracle.jdbc.driver.OracleDriver- 原因: JVM 在类路径中找不到 OJDBC 驱动 JAR 文件。
- 解决方案:
- 确保您已经下载了正确的
ojdbcX.jar。 - 确保您已经将该 JAR 文件正确地添加到项目的类路径中(无论是通过 IDE、Maven 还是命令行)。
- 确保您已经下载了正确的
-
SQLException: No suitable driver found for jdbc:oracle:thin:...- 原因: JDBC URL 的格式不正确,或者
Class.forName()没有成功加载驱动(如果需要)。 - 解决方案:
- 仔细检查您的 JDBC URL,Oracle 的标准格式是
jdbc:oracle:thin:@<host>:<port>:<service_name>或jdbc:oracle:thin:@//<host>:<port>/<service_name>。 - 确保驱动名称拼写正确(虽然通常可以省略
Class.forName)。
- 仔细检查您的 JDBC URL,Oracle 的标准格式是
- 原因: JDBC URL 的格式不正确,或者
-
IO Error: The Network Adapter could not establish the connection- 原因: 这是最常见的网络连接问题,程序无法连接到数据库监听器。
- 解决方案:
- 检查数据库服务: 确认 Oracle 数据库实例(如
XE)正在运行。 - 检查监听器: 在数据库服务器上运行
lsnrctl status命令,确认监听器正在监听正确的端口(默认 1521)。 - 检查主机和端口: 确认 JDBC URL 中的
localhost和1521是正确的,如果数据库不在本机,请使用正确的 IP 地址。 - 检查防火墙: 确保运行数据库的机器和运行 Java 程序的机器之间的防火墙没有阻止 1521 端口。
- 检查 TNSNAMES.ORA (如果使用): 如果您使用的是
jdbc:oracle:thin:@mydb这样的别名,请确保TNSNAMES.ORA文件配置正确。
- 检查数据库服务: 确认 Oracle 数据库实例(如
-
ORA-01017: invalid username/password; logon denied- 原因: 用户名或密码错误。
- 解决方案:
- 仔细检查 JDBC 代码中提供的用户名和密码是否与数据库中的完全一致(注意大小写)。
- 确认该用户是否有权限连接到数据库。
