杰瑞科技汇

Java如何连接Oracle数据库?

  1. 准备工作:在编写代码前必须完成的配置。
  2. 核心代码:使用 JDBC 连接 Oracle 的标准步骤和示例。
  3. 不同连接方式的代码:包括 SID 和 Service Name 两种常见方式。
  4. 最佳实践:使用 try-with-resources 和连接池,避免资源泄露。
  5. 常见问题与解决方案:排查连接失败时可能遇到的问题。

准备工作

在运行 Java 代码之前,请确保你已经完成了以下步骤:

Java如何连接Oracle数据库?-图1
(图片来源网络,侵删)

a. 安装 Oracle JDBC 驱动

你需要 Oracle 数据库的 JDBC 驱动程序(JAR 文件),这个 JAR 文件通常位于 Oracle 客户端安装目录或数据库服务器上。

  • 最新版本:推荐使用最新的 JDBC 驱动,可以从 Oracle 官网下载。
  • 常用版本ojdbc8.jar (适用于 JDK 8) 或 ojdbc11.jar (适用于 JDK 11+)。

b. 添加 JAR 文件到项目

你需要将下载的 JAR 文件添加到你的 Java 项目的类路径中。

  • 对于 Maven 项目:在 pom.xml 文件中添加依赖,这是最推荐的方式。

    <!-- Oracle Database 19c driver -->
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>19.3.0.0</version>
    </dependency>
    <!-- 或者使用更新的版本 -->
    <!-- <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc11</artifactId>
        <version>21.5.0.0</version>
    </dependency> -->
  • 对于 Gradle 项目:在 build.gradle 文件中添加依赖。

    Java如何连接Oracle数据库?-图2
    (图片来源网络,侵删)
    // Oracle Database 19c driver
    implementation 'com.oracle.database.jdbc:ojdbc8:19.3.0.0'
  • 对于手动管理的项目:将 JAR 文件复制到项目的 lib 目录下,并在 IDE (如 IntelliJ IDEA, Eclipse) 中将其添加到库/模块路径中。

c. 准备数据库连接信息

你需要从你的 DBA 或数据库管理员那里获取以下信息:

  • 主机名: 数据库服务器的地址 (localhost168.1.100)。
  • 端口: Oracle 监听器的端口,默认是 1521
  • SID 或 Service Name: 这是标识具体数据库实例的名称。现代 Oracle 数据库更推荐使用 Service Name
    • SID: 一个实例的标识符,在较老的 Oracle 版本中常用。
    • Service Name: 一个更灵活的、可以指向一个或多个数据库实例的逻辑名称,是 Oracle 集群和现代单实例数据库的首选。
  • 用户名: scott
  • 密码: tiger

核心代码示例 (使用 try-with-resources)

这是最现代、最安全的写法,可以自动关闭资源(如 Connection, Statement, ResultSet),避免资源泄露。

使用 Service Name 连接 (推荐)

这是目前最通用的方式,适用于大多数现代 Oracle 数据库。

Java如何连接Oracle数据库?-图3
(图片来源网络,侵删)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class OracleConnectionExample {
    // --- 请根据你的环境修改以下信息 ---
    private static final String DB_URL = "jdbc:oracle:thin:@//<hostname>:<port>/<service_name>";
    private static final String USER = "<your_username>";
    private 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 'Hello from Oracle!' AS message FROM DUAL")) {
            // 检查连接是否成功
            if (conn != null) {
                System.out.println("连接成功!");
            }
            // 处理查询结果
            while (rs.next()) {
                // 假设查询结果列名为 "message"
                String message = rs.getString("message");
                System.out.println("查询结果: " + message);
            }
        } catch (SQLException e) {
            System.err.println("数据库连接或查询失败!");
            e.printStackTrace();
        }
    }
}

使用 SID 连接 (传统方式)

如果你的数据库仍然使用 SID 进行标识,连接 URL 的格式会略有不同。

// ... (import 语句同上) ...
public class OracleConnectionSIDExample {
    // --- 请根据你的环境修改以下信息 ---
    private static final String DB_URL = "jdbc:oracle:thin:@<hostname>:<port>:<sid>";
    private static final String USER = "<your_username>";
    private static final String PASS = "<your_password>";
    // -----------------------------------
    public static void main(String[] args) {
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {
            System.out.println("使用 SID 连接成功!");
            // 在这里执行你的数据库操作...
        } catch (SQLException e) {
            System.err.println("数据库连接失败!");
            e.printStackTrace();
        }
    }
}

不同环境下的连接 URL 格式

连接方式 URL 格式 示例
Service Name (推荐) jdbc:oracle:thin:@//<host>:<port>/<service_name> jdbc:oracle:thin:@//localhost:1521/XE
SID (传统) jdbc:oracle:thin:@<host>:<port>:<sid> jdbc:oracle:thin:@localhost:1521:XE
TNS 名称 (复杂网络) jdbc:oracle:thin:@<tns_name> jdbc:oracle:thin:@my_tns_entry (需要在 tnsnames.ora 文件中配置)
EZConnect (简化连接) jdbc:oracle:thin:<user>/<password>@<host>:<port>/<service_name> jdbc:oracle:thin:scott/tiger@localhost:1521/XE

最佳实践:使用连接池

在生产环境中,绝对不要在每次需要数据库连接时都创建一个新的连接,这会带来巨大的性能开销,应该使用连接池来管理和复用数据库连接。

这里以最流行的 HikariCP 为例。

a. 添加 HikariCP 依赖

如果你使用 Maven,在 pom.xml 中添加:

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.0.1</version> <!-- 使用最新稳定版 -->
</dependency>

b. 使用 HikariCP 创建连接

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class OracleConnectionPoolExample {
    // --- 请根据你的环境修改以下信息 ---
    private static final String JDBC_URL = "jdbc:oracle:thin:@//localhost:1521/XE";
    private static final String DB_USER = "scott";
    private static final String DB_PASSWORD = "tiger";
    // -----------------------------------
    // 创建一个静态的 HikariDataSource 实例,作为全局连接池
    private static HikariDataSource dataSource;
    static {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl(JDBC_URL);
        config.setUsername(DB_USER);
        config.setPassword(DB_PASSWORD);
        // 可选的优化配置
        config.setDriverClassName("oracle.jdbc.OracleDriver");
        config.setMaximumPoolSize(10); // 最大连接数
        config.setMinimumIdle(5);      // 最小空闲连接数
        config.setConnectionTimeout(30000); // 连接超时时间 (ms)
        config.setIdleTimeout(600000);      // 空闲连接超时时间 (ms)
        config.setMaxLifetime(1800000);     // 连接最大存活时间 (ms)
        dataSource = new HikariDataSource(config);
    }
    public static void main(String[] args) {
        // 从连接池中获取一个连接
        try (Connection conn = dataSource.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT SYSDATE AS current_date FROM DUAL")) {
            System.out.println("从连接池成功获取连接!");
            while (rs.next()) {
                System.out.println("当前数据库时间: " + rs.getTimestamp("current_date"));
            }
        } catch (SQLException e) {
            System.err.println("从连接池获取连接或查询失败!");
            e.printStackTrace();
        }
        // 在应用关闭时,关闭连接池 (通常在应用的生命周期结束时执行一次)
        // dataSource.close();
    }
}

常见问题与解决方案

问题 1: java.lang.ClassNotFoundException: oracle.jdbc.OracleDriver

  • 原因: Java 虚拟机在类路径中找不到 Oracle JDBC 驱动的类。
  • 解决方案:
    1. 确保 ojdbcX.jar 文件已下载。
    2. 确保 JAR 文件已正确添加到项目的构建路径/类路径中,检查你的 IDE 或构建工具(Maven/Gradle)的配置。

问题 2: java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:...

  • 原因: 这通常不是驱动找不到,而是 JDBC URL 的格式不正确,或者驱动没有被正确加载。
  • 解决方案:
    1. 仔细检查你的 JDBC URL,确保格式正确(区分 SID 和 Service Name)。
    2. 确保代码中 Class.forName("oracle.jdbc.OracleDriver") 被调用(在现代 JDBC 驱动中,这通常是可选的,但加上它不会错)。
    3. 检查 ojdbcX.jar 是否与你的 JDK 版本兼容(ojdbc8.jar 用于 JDK 8)。

问题 3: java.sql.SQLException: IO Error: The Network Adapter could not establish the connection

  • 原因: 这是网络问题,Java 应用无法连接到指定的主机和端口。
  • 解决方案:
    1. 检查主机名和端口: 确认 <hostname><port> (通常是 1521) 是否正确。
    2. 检查防火墙: 确保运行 Java 应用的机器和 Oracle 服务器之间的防火墙允许 1521 端口的通信。
    3. 检查 Oracle 监听器状态: 登录到 Oracle 服务器,检查监听器是否正在运行。
      # 在 Oracle 服务器上执行
      lsnrctl status

      如果监听器未启动,使用 lsnrctl start 启动它。

问题 4: java.sql.SQLException: ORA-01017: invalid username/password; logon denied

  • 原因: 用户名或密码错误。
  • 解决方案:
    1. 仔细核对代码中的 USERPASS 变量。
    2. 确认该用户是否有权限访问你想连接的数据库。

希望这份详细的指南能帮助你成功连接到 Oracle 数据库!

分享:
扫描分享到社交APP
上一篇
下一篇