使用 JDBC 連接 Oracle 數據庫主要分為四步:加載驅動、建立連接、執行 SQL、釋放資源。現代應用建議配合連接池(HikariCP、Druid)使用,避免頻繁創建銷毀連接的性能開銷。
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<version>23.4.0.0</version>
</dependency>
注意:Oracle 19c/21c/23c 建議使用 ojdbc11(支援 JDK 11+),舊版 ojdbc8 僅支援 JDK 8。驅動類名統一為 oracle.jdbc.OracleDriver。
| 格式 | 適用場景 | 範例 |
|---|---|---|
| Thin 驅動(純 Java) | 最常用,無需 Oracle Client | jdbc:oracle:thin:@//host:port/service_name |
| SID 模式(舊版) | 兼容老系統 | jdbc:oracle:thin:@host:port:SID |
| TNS 名稱 | 配置 tnsnames.ora | jdbc:oracle:thin:@TNS_ALIAS |
| LDAP/OID | 企業級統一目錄 | jdbc:oracle:thin:@ldap://host:port/dn,cn=OracleContext |
public void queryUsers() {
String url = "jdbc:oracle:thin:@//localhost:1521/ORCLPDB1";
String user = "system";
String password = "your_password";
String sql = "SELECT user_id, username FROM users WHERE status = ?";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, 1); // 設置參數,防止 SQL 注入
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
long id = rs.getLong("user_id");
String name = rs.getString("username");
System.out.printf("ID: %d, Name: %s%n", id, name);
}
}
} catch (SQLException e) {
// 統一異常處理,記錄錯誤碼與 SQLState
System.err.printf("SQL Error: %d, State: %s, Msg: %s%n",
e.getErrorCode(), e.getSQLState(), e.getMessage());
throw new RuntimeException("數據庫查詢失敗", e);
}
}
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:oracle:thin:@//localhost:1521/ORCLPDB1");
config.setUsername("system");
config.setPassword("your_password");
config.setDriverClassName("oracle.jdbc.OracleDriver");
// 核心池參數調優
config.setMaximumPoolSize(20); // 最大連接數
config.setMinimumIdle(5); // 最小空閒連接
config.setIdleTimeout(300000); // 空閒超時 5 分鐘
config.setMaxLifetime(1800000); // 連接最大壽命 30 分鐘
config.setConnectionTimeout(30000); // 獲取連接超時 30 秒
config.setLeakDetectionThreshold(60000); // 洩漏檢測 60 秒
// Oracle 專項優化
config.addDataSourceProperty("oracle.net.CONNECT_TIMEOUT", "10000");
config.addDataSourceProperty("oracle.jdbc.ReadTimeout", "60000");
config.setPoolName("Oracle-HikariCP-Pool");
HikariDataSource dataSource = new HikariDataSource(config);
// 使用連接池
try (Connection conn = dataSource.getConnection()) {
// 業務邏輯...
}
lsnrctl status 監聽器註冊的服務名。sqlnet.ora 設置 SQLNET.ALLOWED_LOGON_VERSION_SERVER=11 或升級驅動。TIMESTAMP WITH TIME ZONE 偏移,啟動參數加 -Duser.timezone=Asia/Shanghai 或連接屬性 oracle.jdbc.timezoneAsRegion=false。ResultSet.getClob() / getBlob() 獲取流式讀寫。PreparedStatement 防注入、利用執行計劃緩存。Connection/Statement/ResultSet。DriverManager.getConnection。SELECT 1 FROM DUAL 防止防火牆斷開空閒連接。