Oracle 11g Release 2 引入了新的連接語法,傳統的 SID 模式連接字串會導致 ORA-12505, TNS:listener does not currently know of SID given in connect descriptor 錯誤。本文詳細說明正確的連接方式、驅動選擇、連接池配置與常見問題排查。
Oracle 11g R2 監聽器默認註冊服務名而非 SID。舊式連接字串使用 :SID 語法,監聽器無法識別。
| 模式 | 語法 | 適用版本 | 示例 |
|---|---|---|---|
| 服務名 (推薦) | jdbc:oracle:thin:@//host:port/service_name | 11g R2+ | jdbc:oracle:thin:@//192.168.1.100:1521/ORCL |
| SID (舊式) | jdbc:oracle:thin:@host:port:SID | 11g R1 及之前 | jdbc:oracle:thin:@192.168.1.100:1521:ORCL |
| TNSNAMES | jdbc:oracle:thin:@tns_alias | 所有版本 | 需配置 tnsnames.ora 並設 TNS_ADMIN |
關鍵差異:服務名模式使用雙斜槓 // 和單斜槓 / 分隔服務名,而非冒號 :。
import java.sql.*;
public class Oracle11gJdbcDemo {
// 配置常量(實際項目請外部化配置)
private static final String DRIVER = "oracle.jdbc.OracleDriver"; // 11g+ 統一驅動類名
private static final String URL = "jdbc:oracle:thin:@//localhost:1521/ORCL"; // 服務名模式
private static final String USER = "scott";
private static final String PASSWORD = "tiger";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 加載驅動 (JDBC 4.0+ 可省略,但建議保留兼容舊容器)
Class.forName(DRIVER);
// 2. 建立連接
conn = DriverManager.getConnection(URL, USER, PASSWORD);
System.out.println("連接成功!數據庫版本: " + conn.getMetaData().getDatabaseProductVersion());
// 3. 執行查詢
stmt = conn.createStatement();
String sql = "SELECT * FROM EMP WHERE ROWNUM <= 5";
rs = stmt.executeQuery(sql);
// 4. 處理結果
while (rs.next()) {
System.out.printf("EMPNO: %d, ENAME: %s, JOB: %s, SAL: %.2f%n",
rs.getInt("EMPNO"),
rs.getString("ENAME"),
rs.getString("JOB"),
rs.getDouble("SAL"));
}
} catch (ClassNotFoundException e) {
System.err.println("驅動類未找到,請檢查 ojdbc*.jar 是否在 classpath 中");
e.printStackTrace();
} catch (SQLException e) {
System.err.println("SQL 執行錯誤: " + e.getMessage());
System.err.println("SQLState: " + e.getSQLState());
System.err.println("ErrorCode: " + e.getErrorCode()); // ORA-錯誤碼
e.printStackTrace();
} finally {
// 5. 關鍵:逆序關閉資源
closeQuietly(rs);
closeQuietly(stmt);
closeQuietly(conn);
}
}
private static void closeQuietly(AutoCloseable resource) {
if (resource != null) {
try { resource.close(); } catch (Exception ignored) {}
}
}
}
| JAR 文件 | JDK 版本 | Oracle 版本 | 備註 |
|---|---|---|---|
ojdbc8.jar | JDK 8+ | 12c, 18c, 19c, 21c | 推薦新項目使用 |
ojdbc7.jar | JDK 7/8 | 11g R2, 12c R1 | 11g R2 專用 |
ojdbc6.jar | JDK 6/7 | 11g R1/R2 | 舊項目維護 |
下載地址:Oracle 官網 JDBC/UCP 下載頁(需 Oracle 帳號)。
// application.properties / yml
spring.datasource.url=jdbc:oracle:thin:@//db-host:1521/ORCL
spring.datasource.username=app_user
spring.datasource.password=secure_pass
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
# HikariCP 核心參數
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-test-query=SELECT 1 FROM DUAL
spring.datasource.hikari.pool-name=OracleHikariPool
| 錯誤碼 | 含義 | 解決方向 |
|---|---|---|
| ORA-12505 | 監聽器不知 SID | 改用服務名語法 @//host:port/service |
| ORA-12514 | 監聽器不知服務 | 檢查服務名拼寫、數據庫實例是否註冊到監聽器 |
| ORA-01017 | 用戶名/密碼錯誤 | 檢查大小寫、鎖定狀態、密碼過期 |
| ORA-12170 | 連接超時 | 檢查防火牆、VPN、主機名解析、監聽器端口 |
| ORA-28000 | 帳號鎖定 | DBA 解鎖 ALTER USER user ACCOUNT UNLOCK |
connection.setClientInfo("OCSID.APP_CONTEXT", "value") 減少圍繞查詢oracle.jdbc.implicitConnectionCache=truestmt.addBatch() + executeBatch() 大幅提升寫入效能stmt.setFetchSize(100) 減少網絡往返ojdbc8.jar 或 ojdbc11.jar (JDK 11+)oracle.jdbc.fanEnabled=true 獲得計劃性維護通知Universal Connection Pool (UCP) 替換 HikariCP 獲得更深度 Oracle 整合