必须用ojdbc11(如23.7.0.24.07),因其声明module-info.java支持jpms;url须用服务名格式(如/xe或//host:port/service_name);module-info.java中必须显式requires oracle.jdbc,否则drivermanager报no suitable driver。

Java 17 连不上 Oracle,八成不是 HikariCP 的问题,而是驱动、URL 或模块系统三者之一没对齐。ojdbc8 在 Java 17 模块化环境下会直接类加载失败,ojdbc11 才是唯一可靠选择;URL 写成 jdbc:oracle:thin:@host:1521:XE(SID 格式)大概率报 ORA-12505;module-info.java 缺 requires oracle.jdbc 会导致运行时报 No suitable driver。
必须用 ojdbc11,不是 ojdbc8
Java 17 启用模块系统(JPMS),而 ojdbc8 没声明 module-info.java,会被加载为 unnamed module,导致 java.lang.NoClassDefFoundError: javax/sql/DataSource 或 module not found: java.xml.bind。ojdbc11(如 com.oracle.database.jdbc:ojdbc11:23.7.0.24.07)已正确定义模块名 oracle.jdbc,且兼容 Java 17+。
- Maven 中显式排除旧驱动:
<exclusion><groupid>com.oracle</groupid><artifactid>ojdbc6</artifactid></exclusion> - 不要用 Maven Central 上非 Oracle 签名的“ojdbc11”镜像包——它们常缺模块声明
- 启动 JVM 时无需
--add-opens(ojdbc11 已适配),但若用到反射操作 Oracle 特有类,才需加--add-opens java.base/java.lang=ALL-UNNAMED
URL 必须用 service_name,不能用 SID
Oracle 12c+(含 19c/21c)默认启用多租户和 PDB,@host:port:SID 格式在容器化或 RAC 环境下基本失效,连接能建上但立即抛 ORA-12505。正确格式是双斜杠 + service_name:
- ✅ 正确:
jdbc:oracle:thin:@//localhost:1521/ORCLPDB1(注意开头两个/) - ✅ 本地 XE 可用:
jdbc:oracle:thin:@localhost:1521/XE(注意是/XE,不是:XE) - ❌ 错误:
jdbc:oracle:thin:@localhost:1521:ORCL(SID 格式,已淘汰) - 不确定 service_name 时,登录 DB 执行:
SELECT SYS_CONTEXT('USERENV', 'SERVICE_NAME') FROM DUAL
module-info.java 必须显式 requires oracle.jdbc
模块化项目(含 module-info.java)中,仅靠 Maven 依赖或 JVM 参数无法让模块系统识别 Oracle 驱动。DriverManager 会因类加载器隔离找不到驱动类,抛出 SQLException: No suitable driver。
- 必须写:
requires oracle.jdbc;(不是requires transitive oracle.jdbc) - 完整示例:
module my.app { requires java.sql; requires oracle.jdbc; exports com.myapp.db; } - Spring Boot 用户注意:若使用
spring-boot-starter-jdbc,它不强制模块化,但一旦你加了module-info.java,就必须补上这行,否则编译或运行都过不去
connection-init-sql 和 auto-commit 是 Oracle 事务正确的前提
Oracle JDBC 驱动默认 autoCommit = true,这会导致 Spring @Transactional 失效、手动 conn.commit() 无效果,甚至出现静默数据丢失。HikariCP 不干预该状态,必须主动设为 false 并初始化 session。
- 必须配置:
config.setAutoCommit(false) - 推荐
connection-init-sql:ALTER SESSION SET CURRENT_SCHEMA = MY_SCHEMA(避免每次 SQL 写 schema 前缀) - 也可用:
SET AUTOCOMMIT OFF(仅 thin 模式支持,更底层) - 别信
connection-test-query:HikariCP 5.0+ 默认走isValid(),Oracle 支持且更快;设SELECT 1 FROM DUAL反而多一次 round-trip
真正容易被忽略的是驱动版本与模块声明的耦合性——ojdbc11 不只是“支持 Java 17”,它是唯一能让 DriverManager.getConnection() 在模块路径下成功解析并加载驱动类的版本。哪怕 URL 和参数全对,缺了 requires oracle.jdbc,应用启动那一刻就注定失败。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











