杰瑞科技汇

Java连接Oracle JDBC,驱动与配置怎么搞?

目录

  1. 环境准备
    • 安装 Oracle 数据库
    • 下载 JDBC 驱动 (OJDBC)
    • 配置 Java 开发环境
  2. 核心步骤
    • 添加 JDBC 驱动到项目
    • 编写 Java 连接代码
  3. 完整代码示例
    • 基础版(不推荐用于生产)
    • 推荐版(使用 try-with-resources
    • DML 操作示例(增删改)
  4. 最佳实践
    • 使用连接池
    • 加载驱动的方式
    • 使用 PreparedStatement
  5. 常见问题与解决方案
    • ClassNotFoundException
    • SQLException: No suitable driver found
    • IO Error: The Network Adapter could not establish the connection
    • ORA-01017: invalid username/password; logon denied

环境准备

在开始编码之前,请确保您已经准备好以下环境:

Java连接Oracle JDBC,驱动与配置怎么搞?-图1
(图片来源网络,侵删)

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"。

  1. 访问 Oracle 官方下载页面:Oracle JDBC/ODBC Drivers
  2. 根据您的 Oracle 数据库版本和 Java 版本选择合适的驱动,对于 Oracle 19c 数据库,您可以选择 ojdbc8.jar(适用于 Java 8)或 ojdbc10.jar(适用于 Java 10 及以上)。
  3. 下载 .jar 文件并记住它的存放位置。

c. 配置 Java 开发环境

确保您的系统已安装 JDK 并配置好了 JAVA_HOMEPATH 环境变量,并且可以使用 javajavac 命令。


核心步骤

a. 添加 JDBC 驱动到项目

您需要将下载的 OJDBC JAR 文件添加到您的 Java 项目的类路径中,根据您使用的开发工具,方法不同:

Java连接Oracle JDBC,驱动与配置怎么搞?-图2
(图片来源网络,侵删)
  • 使用 IDE (如 IntelliJ IDEA 或 Eclipse):

    1. 右键点击您的项目。
    2. 选择 "Open Module Settings" (IntelliJ) 或 "Build Path" -> "Configure Build Path" (Eclipse)。
    3. 在 "Libraries" 或 "Modules" -> "Dependencies" 选项卡中,点击 "Add" 或 "Add External JARs..."。
    4. 选择您下载的 ojdbcX.jar 文件。
  • 使用命令行 (Maven): 这是最推荐的方式,在您的 pom.xml 文件中添加以下依赖:

    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>19.3.0.0</version> <!-- 请使用您下载的驱动版本 -->
    </dependency>

    Maven 会自动下载并管理依赖。

  • 使用命令行 (手动编译): 如果您不使用构建工具,编译和运行时需要手动指定 JAR 路径。

    Java连接Oracle JDBC,驱动与配置怎么搞?-图3
    (图片来源网络,侵删)
    # 编译
    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 数据库主要涉及以下几个步骤:

  1. 加载驱动: 使用 Class.forName() 加载 Oracle 的 JDBC 驱动类。
  2. 获取连接: 使用 DriverManager.getConnection() 方法,提供数据库 URL、用户名和密码来创建一个 Connection 对象。
  3. 创建语句: 通过 Connection 对象创建 StatementPreparedStatement 来执行 SQL。
  4. 执行查询: 使用 executeQuery() 执行查询,返回 ResultSet
  5. 处理结果: 遍历 ResultSet 读取数据。
  6. 关闭资源: 非常重要! 按照从后到前的顺序关闭 ResultSetStatementConnection,以释放数据库资源。

完整代码示例

假设您的数据库信息如下:

  • 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(参数不同)性能更好。


最佳实践

  1. 使用连接池: 在生产环境中,绝对不要每次操作都创建和销毁连接,这会带来巨大的性能开销,应该使用连接池(如 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();
    }
  2. 加载驱动的方式: 在现代 JDBC 驱动(从 JDBC 4.0 开始)中,加载驱动是可选的,驱动程序管理器会自动在类路径中查找可用的驱动。Class.forName("oracle.jdbc.driver.OracleDriver") 这一行代码在现代 Java 应用中通常可以省略。

  3. 使用 PreparedStatement: 如前所述,始终使用 PreparedStatement 来执行 SQL,特别是当 SQL 包含来自用户输入的参数时,这是防止 SQL 注入攻击的黄金法则。


常见问题与解决方案

  1. ClassNotFoundException: oracle.jdbc.driver.OracleDriver

    • 原因: JVM 在类路径中找不到 OJDBC 驱动 JAR 文件。
    • 解决方案:
      • 确保您已经下载了正确的 ojdbcX.jar
      • 确保您已经将该 JAR 文件正确地添加到项目的类路径中(无论是通过 IDE、Maven 还是命令行)。
  2. 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)。
  3. IO Error: The Network Adapter could not establish the connection

    • 原因: 这是最常见的网络连接问题,程序无法连接到数据库监听器。
    • 解决方案:
      • 检查数据库服务: 确认 Oracle 数据库实例(如 XE)正在运行。
      • 检查监听器: 在数据库服务器上运行 lsnrctl status 命令,确认监听器正在监听正确的端口(默认 1521)。
      • 检查主机和端口: 确认 JDBC URL 中的 localhost1521 是正确的,如果数据库不在本机,请使用正确的 IP 地址。
      • 检查防火墙: 确保运行数据库的机器和运行 Java 程序的机器之间的防火墙没有阻止 1521 端口。
      • 检查 TNSNAMES.ORA (如果使用): 如果您使用的是 jdbc:oracle:thin:@mydb 这样的别名,请确保 TNSNAMES.ORA 文件配置正确。
  4. ORA-01017: invalid username/password; logon denied

    • 原因: 用户名或密码错误。
    • 解决方案:
      • 仔细检查 JDBC 代码中提供的用户名和密码是否与数据库中的完全一致(注意大小写)。
      • 确认该用户是否有权限连接到数据库。
分享:
扫描分享到社交APP
上一篇
下一篇