杰瑞科技汇

Java连接Oracle11g有哪些关键步骤?

核心概念

要连接 Oracle 数据库,Java 程序需要一个“桥梁”,这个桥梁就是 JDBC (Java Database Connectivity) 驱动程序,Oracle 提供了官方的 JDBC 驱动,你需要将其添加到你的项目中。

Java连接Oracle11g有哪些关键步骤?-图1
(图片来源网络,侵删)

第一步:获取 Oracle JDBC 驱动

Oracle 11g 数据库通常使用 ojdbc6.jar (适用于 JDK 6, 7, 8) 或 ojdbc8.jar (适用于 JDK 8 及以上,但兼容 11g) 驱动。

如何获取?

  1. Oracle 官方下载

    • 访问 Oracle 官方网站:Oracle Database Downloads
    • 找到 "Previous Releases" 部分,选择 "Oracle Database 11g Release 2" (11.2.0.x)。
    • 在下载页面中,你需要接受许可协议,然后找到 "ODBC/JDBC" 部分下载 ojdbc6.jar
    • 注意:你需要拥有一个免费的 Oracle 账号才能下载。
  2. Maven 依赖 (推荐): 如果你使用 Maven 管理项目,这是最简单的方式,在 pom.xml 文件中添加以下依赖:

    Java连接Oracle11g有哪些关键步骤?-图2
    (图片来源网络,侵删)
    <!-- 对于 JDK 8 及以下版本 -->
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>11.2.0.4</version> <!-- 可以使用 11.2.0.x 的任意版本 -->
    </dependency>
    <!-- 对于 JDK 11 及以上版本,使用 ojdbc8,它也兼容 11g -->
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>19.3.0.0</version> <!-- 使用较新的版本通常没问题 -->
    </dependency>
  3. Gradle 依赖: 如果你使用 Gradle,在 build.gradle 文件中添加:

    // 对于 JDK 8 及以下版本
    implementation 'com.oracle.database.jdbc:ojdbc6:11.2.0.4'
    // 对于 JDK 11 及以上版本
    implementation 'com.oracle.database.jdbc:ojdbc8:19.3.0.0'

第二步:编写 Java 连接代码

以下是几种常见的连接方式,从简单到推荐。

基本连接示例 (硬编码不推荐)

这种方式最直接,但强烈不推荐用于生产环境,因为密码等敏感信息硬编码在代码中。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class OracleBasicJdbc {
    // 数据库连接信息
    private static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
    // localhost: 如果数据库在本地
    // 1521: Oracle 默认监听端口
    // ORCL: 数据库服务名 (SID),你的可能是 XE, ORCLPDB1 等,需要根据实际情况修改
    private static final String USER = "scott"; // 你的数据库用户名
    private static final String PASS = "tiger"; // 你的数据库密码
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            // 1. 注册 JDBC 驱动 (对于较新版本的 JDBC 驱动,这步通常是可选的)
            Class.forName("oracle.jdbc.driver.OracleDriver");
            // 2. 打开连接
            System.out.println("正在连接到 Oracle 数据库...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);
            System.out.println("连接成功!");
            // 3. 创建执行语句
            stmt = conn.createStatement();
            String sql = "SELECT * FROM emp WHERE ROWNUM <= 5"; // 查询 emp 表的前5条数据
            ResultSet rs = stmt.executeQuery(sql);
            // 4. 处理结果集
            System.out.println("员工ID\t员工姓名");
            while (rs.next()) {
                // 通过列名获取,更具可读性
                int id = rs.getInt("EMPNO");
                String name = rs.getString("ENAME");
                System.out.println(id + "\t" + name);
            }
            // 5. 关闭资源
            rs.close();
            stmt.close();
            conn.close();
        } catch (ClassNotFoundException e) {
            System.err.println("找不到 Oracle JDBC 驱动类,请检查 ojdbc.jar 是否在 classpath 中。");
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println("数据库连接或查询出错!");
            e.printStackTrace();
        } finally {
            // 确保在 finally 块中关闭资源,防止资源泄漏
            try {
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
    }
}

使用 try-with-resources (推荐)

Java 7 引入了 try-with-resources 语句,它可以自动实现 AutoCloseable 接口的对象(如 Connection, Statement, ResultSet),无需在 finally 块中手动关闭,代码更简洁、安全。

Java连接Oracle11g有哪些关键步骤?-图3
(图片来源网络,侵删)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class OracleJdbcWithTryWithResources {
    private static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
    private static final String USER = "scott";
    private static final String PASS = "tiger";
    public static void main(String[] args) {
        // try-with-resources 会自动关闭 conn, stmt, rs
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM emp WHERE ROWNUM <= 5")) {
            System.out.println("连接成功!");
            System.out.println("员工ID\t员工姓名");
            while (rs.next()) {
                int id = rs.getInt("EMPNO");
                String name = rs.getString("ENAME");
                System.out.println(id + "\t" + name);
            }
        } catch (SQLException e) {
            System.err.println("数据库操作出错!");
            e.printStackTrace();
        }
    }
}

第三步:连接字符串详解

jdbc:oracle:thin:@<host>:<port>:<service_name> 是最常用的连接字符串格式。

  • jdbc:oracle:thin: 指定使用 JDBC 的 "thin" 驱动,这是一个纯 Java 的驱动,无需客户端库。
  • @<host>: 数据库服务器的 IP 地址或主机名。localhost, 168.1.100, db.example.com
  • <port>: 数据库监听的端口号,默认是 1521
  • <service_name>: 这是 Oracle 数据库的标识。非常重要!
    • SID: 早期版本的 Oracle 使用 SID (System Identifier) 来标识实例,如 ORCL, XE
    • Service Name: Oracle 9i 及以后版本推荐使用 Service Name,它更灵活,可以指向一个或多个实例。ORCLPDB1 (在 CDB/PDB 架构中) 或 ORCL

如何确认你的 Service Name 或 SID?

  1. *使用 SQLPlus 连接**:

    sqlplus / as sysdba

    然后执行以下查询:

    -- 查看所有服务名
    SELECT name FROM v$services;
    -- 查看当前实例的 SID
    SELECT instance_name FROM v$instance;
  2. 查看 tnsnames.ora 文件: 这个文件通常位于 Oracle 客户端安装目录的 network/admin 目录下,它定义了数据库的网络连接别名。


第四步:常见问题与解决方案

  1. java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver

    • 原因: JVM 的类路径中没有找到 ojdbc.jar 文件。
    • 解决方案:
      • 如果你使用 IDE (如 IntelliJ IDEA, Eclipse), 确保将 ojdbc.jar 文件添加到项目的 Libraries/Dependencies 中。
      • 如果你使用命令行编译和运行,确保使用 -cp-classpath 选项指定 jar 文件的路径:
        java -cp ".:/path/to/ojdbc6.jar" OracleJdbcWithTryWithResources
  2. java.sql.SQLException: Io 异常: The Network Adapter could not establish the connection

    • 原因: 程序无法连接到指定的主机和端口。
    • 解决方案:
      • 检查主机和端口: 确认 DB_URL 中的 localhost1521 是否正确,如果数据库不在本机,请使用正确的 IP 地址。
      • 检查 Oracle 监听器: 确保Oracle数据库的监听器正在运行,在数据库服务器上执行 lsnrctl status 命令检查。
      • 检查防火墙: 确保运行数据库的服务器的防火墙允许来自你应用服务器的 1521 端口入站连接。
  3. java.sql.SQLException: ORA-01017: invalid username/password; logon denied

    • 原因: 用户名或密码错误。
    • 解决方案: 仔细核对代码中的 USERPASS 变量是否与数据库中的用户名和密码完全一致(注意大小写)。
  4. java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1

    • 原因: 这通常是一个底层错误,可能由权限问题、表空间不足或数据库内部错误引起。
    • 解决方案: 检查连接用户是否有足够的权限执行操作,查看数据库的 alert log 文件以获取更详细的错误信息。

第五步:最佳实践

  1. 使用连接池: 在任何生产环境中,绝对不要每次请求都创建一个新的数据库连接,创建和销毁连接是非常昂贵的操作,应该使用连接池来管理和复用连接。

    • 推荐框架: HikariCP (目前性能最好的连接池), Apache DBCP2, C3P0

    • 示例 (使用 HikariCP):

      <!-- 在 pom.xml 中添加 HikariCP 依赖 -->
      <dependency>
          <groupId>com.zaxxer</groupId>
          <artifactId>HikariCP</artifactId>
          <version>5.0.1</version>
      </dependency>
      import com.zaxxer.hikari.HikariConfig;
      import com.zaxxer.hikari.HikariDataSource;
      import java.sql.Connection;
      import java.sql.ResultSet;
      import java.sql.Statement;
      public class OracleHikariCPExample {
          private static HikariDataSource dataSource;
          static {
              HikariConfig config = new HikariConfig();
              config.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:ORCL");
              config.setUsername("scott");
              config.setPassword("tiger");
              config.setDriverClassName("oracle.jdbc.driver.OracleDriver");
              // 连接池配置
              config.setMaximumPoolSize(10);
              config.setMinimumIdle(5);
              config.setConnectionTimeout(30000); // 30 seconds
              dataSource = new HikariDataSource(config);
          }
          public static void main(String[] args) {
              try (Connection conn = dataSource.getConnection();
                   Statement stmt = conn.createStatement();
                   ResultSet rs = stmt.executeQuery("SELECT * FROM emp WHERE ROWNUM <= 5")) {
                   // ... 执行查询
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
      }
  2. 配置外部化: 将数据库连接信息(URL, 用户名, 密码)存储在外部配置文件(如 config.properties)或环境变量中,而不是硬编码在代码里。

  3. 使用 PreparedStatement: 对于参数化查询,始终使用 PreparedStatement 而不是 Statement,它可以防止 SQL 注入攻击,并且对于重复执行的查询性能更好。

  4. 处理异常和关闭资源: 始终使用 try-with-resources 或在 finally 块中确保所有数据库资源(Connection, Statement, ResultSet)都被正确关闭,避免资源泄漏。

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