杰瑞科技汇

Java如何连接Oracle数据库?

目录

  1. 准备工作
    • 安装 Oracle 数据库
    • 获取数据库连接信息
    • 下载 Oracle JDBC 驱动
  2. 核心步骤
    • 添加驱动到项目
    • 编写 Java 连接代码
  3. 代码示例
    • 使用 JDBC ojdbc8.jar (推荐)
    • 使用 JDBC ojdbc11.jar (面向未来)
    • 使用第三方连接池 (如 HikariCP)
  4. 最佳实践
    • 使用 try-with-resources 管理资源
    • 使用连接池
    • 使用 PreparedStatement 防止 SQL 注入
    • 处理异常
  5. 常见问题与解决方案

准备工作

在开始编码之前,请确保你已经具备以下条件:

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

a. 安装 Oracle 数据库

你需要一个可访问的 Oracle 数据库实例,这可以是本地安装的 Oracle Database,也可以是远程服务器上的数据库,甚至是 Oracle Cloud 的免费版。

b. 获取数据库连接信息

你需要从你的 DBA(数据库管理员)或 Oracle Cloud 控制台获取以下关键信息:

  • 主机名: 数据库服务器的地址 (localhostmydb.oracle.com)。
  • 端口号: Oracle 数据库监听的端口 (默认是 1521)。
  • 服务名: 数据库的全局数据库名称 (ORCLCDB.localdomainXEPDB1)。这是 Oracle 推荐的连接标识符。
  • SID: 系统标识符,是较老的方式,如果你的 DBA 给了你 SID,你也可以使用它。
  • 用户名: 用于连接数据库的用户名 (scott, hr, 或你自己的用户)。
  • 密码: 对应用户的密码。

c. 下载 Oracle JDBC 驱动

Java 通过 JDBC (Java Database Connectivity) 规范与数据库交互,Oracle 提供了实现此规范的驱动程序。

  • 下载地址: Oracle JDBC 驱动下载页面
  • 选择版本:
    • ojdbc8.jar: 针对 Java 8 和更高版本,这是目前最常用、最稳定的版本,适用于大多数项目。
    • ojdbc11.jar: 针对 Java 11 及更高版本,完全基于 Java 模块化系统 (JPMS),如果你正在使用 Java 11+,并且你的项目是模块化的,这是一个不错的选择。

下载完成后,你会得到一个 .jar 文件。

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

核心步骤

a. 添加驱动到项目

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

  • 对于 Maven 项目 (推荐): 在你的 pom.xml 文件中添加以下依赖,请根据你下载的版本选择一个。

    使用 ojdbc8:

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

    使用 ojdbc11:

    Java如何连接Oracle数据库?-图3
    (图片来源网络,侵删)
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc11</artifactId>
        <version>21.5.0.0</version> <!-- 请使用你下载的版本号 -->
    </dependency>
  • 对于 Gradle 项目: 在你的 build.gradle 文件中添加:

    // 使用 ojdbc8
    implementation 'com.oracle.database.jdbc:ojdbc8:19.3.0.0' // 请使用你下载的版本号
    // 使用 ojdbc11
    implementation 'com.oracle.database.jdbc:ojdbc11:21.5.0.0' // 请使用你下载的版本号
  • 对于手动管理的项目: 将 .jar 文件复制到项目的 lib 目录下,并在你的 IDE (如 IntelliJ IDEA 或 Eclipse) 中将其添加到库/模块路径中。

b. 编写 Java 连接代码

连接 Oracle 数据库的基本流程是固定的:

  1. 加载 JDBC 驱动。
  2. 创建数据库连接。
  3. 创建 StatementPreparedStatement 对象。
  4. 执行 SQL 查询并处理结果。
  5. 关闭所有资源。

代码示例

示例 1: 使用 JDBC ojdbc8.jar (最常用)

这是最经典的连接方式,适用于 Java 8 及以上环境。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class OracleJdbcExample {
    // 数据库连接信息 - 请替换为你自己的信息
    private static final String DB_URL = "jdbc:oracle:thin:@//<hostname>:<port>/<service_name>";
    private static final String USER = "<username>";
    private static final String PASS = "<password>";
    public static void main(String[] args) {
        // try-with-resources 语句会自动关闭资源
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT 'Hello Oracle' as message FROM DUAL")) {
            // 1. 加载驱动 (对于 ojdbc8.jar, 在 JDBC 4.0+ 中是可选的,但显式调用更清晰)
            // Class.forName("oracle.jdbc.OracleDriver");
            System.out.println("成功连接到 Oracle 数据库!");
            // 2. 执行查询
            while (rs.next()) {
                // 通过列名获取数据
                String message = rs.getString("message");
                System.out.println("查询结果: " + message);
            }
        } catch (SQLException e) {
            System.err.println("连接数据库失败!");
            e.printStackTrace();
        }
    }
}

如何替换连接字符串:

  • <hostname> 替换为你的数据库主机名或 IP 地址。
  • <port> 替换为端口号 (通常是 1521)。
  • <service_name> 替换为你的数据库服务名。
  • 格式: jdbc:oracle:thin:@//<host>:<port>/<service_name>

连接字符串的几种形式:

  • 使用服务名 (推荐): jdbc:oracle:thin:@//localhost:1521/XEPDB1
  • 使用 SID (旧式): jdbc:oracle:thin:@localhost:1521:ORCL
  • 使用 TNS 名称 (需要配置 tnsnames.ora): jdbc:oracle:thin:@myOracleDB

示例 2: 使用 JDBC ojdbc11.jar (面向未来)

这个版本与 ojdbc8 的使用方式几乎完全相同,主要区别在于它支持 Java 模块化。

// 代码与 ojdbc8 示例完全一样
// 只需要确保你的项目使用的是 ojdbc11.jar 依赖
// 并且在 module-info.java (如果有的话) 中添加 requires "com.oracle.database.jdbc";

示例 3: 使用第三方连接池 (HikariCP - 强烈推荐)

在实际生产环境中,直接使用 DriverManager 创建连接是非常低效的,每个连接的建立和销毁都有很高的开销,连接池(如 HikariCP, C3P0, DBCP)可以预先创建一组数据库连接,应用程序需要时从池中获取,使用完毕后归还给池,从而大大提高性能。

添加 HikariCP 依赖 (Maven):

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

编写使用 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 OracleHikariExample {
    // HikariCP 配置
    private static HikariConfig config = new HikariConfig();
    private static HikariDataSource ds;
    static {
        // 基础连接信息
        config.setJdbcUrl("jdbc:oracle:thin:@//<hostname>:<port>/<service_name>");
        config.setUsername("<username>");
        config.setPassword("<password>");
        // 连接池优化配置 (推荐)
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        config.addDataSourceProperty("useServerPrepStmts", "true");
        config.addDataSourceProperty("useLocalSessionState", "true");
        config.addDataSourceProperty("rewriteBatchedStatements", "true");
        config.addDataSourceProperty("cacheResultSetMetadata", "true");
        config.addDataSourceProperty("cacheServerConfiguration", "true");
        config.addDataSourceProperty("elideSetAutoCommits", "true");
        config.addDataSourceProperty("maintainTimeStats", "false");
        // 初始化连接池
        ds = new HikariDataSource(config);
    }
    public static void main(String[] args) {
        // 从连接池中获取一个连接
        try (Connection conn = ds.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT 'Hello Oracle from HikariCP' as message FROM DUAL")) {
            System.out.println("从 HikariCP 连接池成功获取连接!");
            while (rs.next()) {
                String message = rs.getString("message");
                System.out.println("查询结果: " + message);
            }
        } catch (SQLException e) {
            System.err.println("获取连接失败!");
            e.printStackTrace();
        }
    }
}

最佳实践

  1. 使用 try-with-resources

    • 如上例所示,Connection, Statement, ResultSet 等都实现了 AutoCloseable 接口,使用 try-with-resources 可以确保这些资源在任何情况下(无论是否发生异常)都会被自动关闭,避免资源泄漏。
  2. 使用连接池

    • 永远不要在应用程序中频繁地创建和销毁数据库连接,对于任何中大型应用,使用 HikariCP 这样的高性能连接池是必须的。
  3. 使用 PreparedStatement

    • 当你的 SQL 语句包含参数时,务必使用 PreparedStatement,它不仅可以防止 SQL 注入攻击,而且数据库可以预编译 SQL 语句,提高执行效率。
      // 错误示例 (易受SQL注入)
      // String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
      // stmt = conn.createStatement();
      // rs = stmt.executeQuery(sql);

    // 正确示例 String sql = "SELECT * FROM users WHERE username = ? AND password = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, username); // 第一个 ? 替换为 username pstmt.setString(2, password); // 第二个 ? 替换为 password rs = pstmt.executeQuery();

  4. 处理异常

    • SQLException 是检查型异常,你必须处理它,至少要打印堆栈跟踪信息以便调试,在生产环境中,应该记录日志。

常见问题与解决方案

Q1: java.lang.ClassNotFoundException: oracle.jdbc.OracleDriver

  • 原因: Java 虚拟机在类路径中找不到 OracleDriver 类。
  • 解决方案: 确保 ojdbc8.jar (或 ojdbc11.jar) 文件已经正确添加到项目的类路径中,对于 Maven/Gradle 项目,检查 pom.xmlbuild.gradle 文件,确保依赖已正确下载。

Q2: IO Error: The Network Adapter could not establish the connection

  • 原因: 这是最常见的网络连接问题。
    • Oracle 数据库服务未启动。
    • 防火墙阻止了到 <hostname>:<port> 的连接。
    • <hostname><port> 错误。
    • 数据库监听器未配置或未正确监听该端口。
  • 解决方案:
    1. 使用 tnsping <service_name> 命令测试 TNS 名称解析是否成功。
    2. 使用 telnet <hostname> <port> 命令测试网络是否可达,如果失败,说明是网络或防火墙问题。
    3. 登录到数据库服务器,检查监听器状态:lsnrctl status

Q3: ORA-12514: TNS:listener does not currently know of service requested in connect descriptor

  • 原因: 客户端提供的 service_name (或 SID) 在数据库监听器中不存在或未注册。
  • 解决方案:
    1. 确认你使用的服务名或 SID 是否正确。
    2. 在数据库服务器上,查询动态性能视图 v$service_namesv$instance 确认正确的名称。
    3. 重启数据库或监听器以确保服务正确注册。

Q4: ORA-01017: invalid username/password; logon denied

  • 原因: 用户名或密码错误。
  • 解决方案: 仔细检查用户名和密码,注意大小写敏感问题,尝试在 SQL*Plus 或类似工具中直接登录以验证凭据。
分享:
扫描分享到社交APP
上一篇
下一篇