杰瑞科技汇

Java如何连接Oracle数据库?

核心原理

Java 通过 JDBC (Java Database Connectivity) API 来与数据库进行交互,JDBC 是一套标准的 Java API,定义了如何连接数据库、执行 SQL 语句、处理结果等。

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

整个过程可以概括为以下几个步骤:

  1. 加载驱动:让 JVM 知道使用哪个数据库的驱动程序。
  2. 获取连接:使用数据库的 URL、用户名和密码,与数据库建立一个网络连接。
  3. 创建语句:通过连接对象,创建一个 StatementPreparedStatement 对象,用于执行 SQL。
  4. 执行 SQL:使用语句对象执行 SQL 查询或更新。
  5. 处理结果:如果是查询,会得到一个 ResultSet 对象,遍历这个对象来获取数据。
  6. 关闭资源:按照“后开先关”的原则,依次关闭 ResultSetStatementConnection,释放数据库资源。

准备工作

在开始编码之前,你需要准备两样东西:

1 Oracle JDBC 驱动

你需要下载 Oracle 的 JDBC 驱动 JAR 包,目前最常用的是 ojdbc8.jar (适用于 JDK 8) 或 ojdbc11.jar (适用于 JDK 11 及以上)。

2 数据库连接信息

你需要从你的 DBA 或系统管理员那里获取以下信息:

Java如何连接Oracle数据库?-图2
(图片来源网络,侵删)
  • 主机名:数据库服务器的 IP 地址或域名。
  • 端口号:Oracle 监听器监听的端口,默认是 1521
  • 服务名/SID:标识你要连接的具体数据库实例,Oracle 10g 及以后版本推荐使用 服务名
  • 用户名:连接数据库的用户名。
  • 密码:连接数据库的密码。

实现方式

有三种主流的方式来实现 Java 连接 Oracle 数据库:

手动下载 JAR 包 (传统方式)

这是最直接的方式,适合小型项目或快速验证。

  1. 下载并添加 JAR 包:将下载的 ojdbc8.jar 文件添加到你的项目类路径 中。

    • 在 IDE (如 IntelliJ IDEA/Eclipse) 中:右键项目 -> Build Path / Project Structure -> Libraries -> Add External JARs...,然后选择你的 ojdbc8.jar 文件。
    • 使用命令行编译运行:需要用 -cp-classpath 参数指定 JAR 包路径。
      # 编译
      javac -cp ".;ojdbc8.jar" YourJavaFile.java
      # 运行
      java -cp ".;ojdbc8.jar" YourJavaFile

      (注意:Windows 使用 分隔路径,Linux/macOS 使用 )

      Java如何连接Oracle数据库?-图3
      (图片来源网络,侵删)
  2. 编写 Java 代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class OracleJdbcDemo {
    // 数据库连接信息
    private static final String DB_URL = "jdbc:oracle:thin:@//your_host:your_port/your_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 语句,可以自动关闭资源
        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")) {
            // 1. 加载驱动 (对于新版本的驱动,这一步通常是可选的,但写上更规范)
            Class.forName("oracle.jdbc.OracleDriver");
            System.out.println("成功连接到 Oracle 数据库!");
            // 2. 执行查询并处理结果
            while (rs.next()) {
                // 通过列名获取数据
                String message = rs.getString("message");
                System.out.println("查询结果: " + message);
            }
        } catch (ClassNotFoundException e) {
            System.err.println("Oracle JDBC 驱动未找到!");
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println("数据库连接或查询失败!");
            e.printStackTrace();
        }
    }
}

使用 Maven/Gradle (推荐方式)

在现代 Java 项目中,强烈推荐使用 Maven 或 Gradle 来管理项目依赖,这样你无需手动下载和添加 JAR 包。

  1. 配置 Maven (pom.xml)

pom.xml 文件中添加 oracle-java-sdk 依赖,推荐使用较新的版本。

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>oracle-jdbc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- Oracle JDBC 驱动依赖 -->
        <!-- 注意:groupId 和 artifactId 可能有变化,请查找最新的 -->
        <!-- 对于 ojdbc8, groupId 通常是 com.oracle.database.jdbc -->
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>19.3.0.0</version>
        </dependency>
    </dependencies>
</project>
  1. 编写 Java 代码

代码与方式一基本相同,Maven 会自动处理类路径,你无需手动加载驱动(Class.forName 在新驱动中通常可以省略,但保留也无妨)。

// 代码同上,但无需手动添加 JAR 包到项目
import java.sql.*;
public class OracleMavenDemo {
    // ... (DB_URL, USER, PASS 定义同上)
    public static void main(String[] args) {
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT SYSDATE as current_date FROM DUAL")) {
            System.out.println("成功连接到 Oracle 数据库!");
            if (rs.next()) {
                Date currentDate = rs.getDate("current_date");
                System.out.println("Oracle 服务器当前时间: " + currentDate);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

使用连接池 (生产环境最佳实践)

在真实的应用中,频繁地创建和销毁数据库连接是非常消耗资源的。连接池 应运而生,它预先创建一组数据库连接,并将它们放入池中,当需要连接时,从池中获取;使用完毕后,将连接归还到池中,而不是关闭。

HikariCP 是目前性能最好的连接池实现之一。

  1. 配置 Maven (pom.xml)

你需要添加 HikariCP 和 Oracle JDBC 驱动的依赖。

<!-- pom.xml -->
<dependencies>
    <!-- Oracle JDBC 驱动 -->
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>19.3.0.0</version>
    </dependency>
    <!-- HikariCP 连接池 -->
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>5.0.1</version>
    </dependency>
</dependencies>
  1. 编写 Java 代码
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 OracleHikariCPDemo {
    public static void main(String[] args) {
        // 1. 配置 HikariCP
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:oracle:thin:@//your_host:your_port/your_service_name");
        config.setUsername("your_username");
        config.setPassword("your_password");
        // 连接池优化参数 (可根据实际情况调整)
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        config.setMaximumPoolSize(10); // 最大连接数
        // 2. 创建数据源
        try (HikariDataSource ds = new HikariDataSource(config)) {
            System.out.println("HikariCP 连接池创建成功!");
            // 3. 从连接池获取连接
            try (Connection conn = ds.getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery("SELECT 'Connection from HikariCP!' as message FROM DUAL")) {
                System.out.println("成功从连接池获取连接并执行查询!");
                if (rs.next()) {
                    System.out.println("查询结果: " + rs.getString("message"));
                }
            } // 连接在这里被自动归还到连接池
        } catch (SQLException e) {
            System.err.println("获取连接或查询失败!");
            e.printStackTrace();
        } // 数据源在这里被关闭
    }
}

常见问题与最佳实践

1 URL 格式

Oracle 的 JDBC URL 有几种格式,推荐使用第一种(服务名格式)。

  • 格式一 (推荐 - 服务名) jdbc:oracle:thin:@//<host>:<port>/<service_name>

    • thin:表示使用纯 Java 实现的瘦客户端驱动。
    • //host:port:主机和端口。
    • /service_name:服务名。
  • 格式二 (SID) jdbc:oracle:thin:@<host>:<port>:<sid>

    这种格式在较老的 Oracle 版本中更常见。

  • 格式三 (TNS) jdbc:oracle:thin:@<TNS_name>

    • TNS_name 是一个在 tnsnames.ora 文件中定义的网络服务名,这种方式需要配置客户端环境,不常用。

2 Class.forName() 还需要吗?

对于 ojdbc8.jar 及更高版本的驱动,不再需要 Class.forName("oracle.jdbc.OracleDriver"),这是因为驱动 JAR 中的 META-INF/services/java.sql.Driver 文件会自动向 JDBC 驱动管理器注册驱动,保留它不会造成 harm,并且可以增加代码的向后兼容性。

3 字符集问题

如果应用程序和数据库使用的字符集不一致,可能会导致乱码(中文显示为 或乱码)。

  • 解决方案:在 JDBC URL 中指定客户端字符集。
    String DB_URL = "jdbc:oracle:thin:@//your_host:your_port/your_service_name?useUnicode=true&characterEncoding=UTF-8";
    // 对于 Oracle,更常用的是
    String DB_URL = "jdbc:oracle:thin:@//your_host:your_port/your_service_name?useFetchSize=50&useServerPrepStmts=true&rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8";

    确保数据库服务端的 NLS_LANG 环境变量也设置为正确的字符集(如 AMERICAN_AMERICA.AL32UTF8)。

4 资源关闭

数据库连接(Connection)、语句(Statement)和结果集(ResultSet)都是非常宝贵的系统资源。必须在使用后关闭它们,否则会导致连接泄漏,最终使数据库无连接可用。

  • 传统方式:在 finally 块中关闭,并确保关闭前不为 null
  • 现代方式 (推荐):使用 try-with-resources 语句,如上面的所有示例所示,它能确保实现了 AutoCloseable 接口的对象在语句块结束时被自动关闭,代码更简洁、安全。

5 SQL 注入

永远不要使用字符串拼接来构建 SQL 语句,这极易受到 SQL 注入攻击。

  • 危险做法

    String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
  • 安全做法:使用 PreparedStatement

    String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
    try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
        pstmt.setString(1, username);
        pstmt.setString(2, password);
        // ... 执行查询
    }

场景 推荐方式 优点 缺点
学习/快速测试 手动下载 JAR 包 简单直接,无需构建工具 依赖管理麻烦,容易版本冲突
标准 Java 项目 Maven/Gradle 依赖管理自动化,版本清晰,可复用 需要学习构建工具
生产环境应用 Maven/Gradle + 连接池 高性能、高可用、资源复用、稳定可靠 配置相对复杂

对于任何严肃的项目,都强烈建议使用 Maven/Gradle 管理依赖,并结合 HikariCP 这样的连接池 来构建健壮的数据库访问层。

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