Oracle 資料庫是企業級應用主流選擇。本文以 Oracle 8i/9i/10g/11g 為例,講解 JSP 直連與生產級 JNDI 資料源兩種模式,涵蓋 Thin/OCI 驅動選擇、連線字串、常見錯誤排查與架構演進建議。
| 組件 | 版本/說明 |
|---|---|
| JDK | 1.4+ (Oracle 11g+ 需 JDK 6+) |
| Oracle 驅動 | ojdbc14.jar` (JDK 1.4)、`ojdbc6.jar` (JDK 6)、`ojdbc8.jar` (JDK 8+) |
| 驅動類名 | oracle.jdbc.driver.OracleDriver (舊) / oracle.jdbc.OracleDriver (新) |
<%@ page contentType="text/html; charset=UTF-8" import="java.sql.*" %>
<%
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 載入驅動
Class.forName("oracle.jdbc.OracleDriver").newInstance();
// 2. Thin 模式連線字串 (純 Java,無需 Oracle Client)
// 格式: jdbc:oracle:thin:@host:port:SID
// 或: jdbc:oracle:thin:@//host:port/service_name
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String user = "scott";
String password = "tiger";
conn = DriverManager.getConnection(url, user, password);
// 3. 可滾動、可更新結果集
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
// 4. 執行查詢
rs = stmt.executeQuery("SELECT * FROM test");
while (rs.next()) {
out.println("欄位1: " + rs.getString(1) + "
");
out.println("欄位2: " + rs.getString(2) + "
");
}
out.println("資料庫操作成功!");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 5. 逆序關閉
try { if (rs != null) rs.close(); } catch (Exception ignore) {}
try { if (stmt != null) stmt.close(); } catch (Exception ignore) {}
try { if (conn != null) conn.close(); } catch (Exception ignore) {}
}
%>
| 參數 | 說明 | 建議值 |
|---|---|---|
| 驅動類型 | Thin (Type 4) vs OCI (Type 2) | Thin: 部署簡單、跨平台;OCI: 需安裝 Oracle Client、效能略優 |
| SID vs Service Name | SID: 實例唯一標識;Service Name: 邏輯服務名,支援 RAC | 現代環境優先 Service Name |
| 字符集 | JDBC 自動轉換,NLS_LANG 影響 | DB/客戶端均用 AL32UTF8 |
| Statement 類型 | TYPE_FORWARD_ONLY (預設)、TYPE_SCROLL_INSENSITIVE、TYPE_SCROLL_SENSITIVE | 僅需順序讀用預設,需隨機存取用 INSENSITIVE |
| 錯誤代碼/現象 | 原因 | 解決 |
|---|---|---|
| ORA-12505 / TNS:listener does not currently know of SID | SID 錯誤、Listener 未註冊該實例 | `lsnrctl status` 確認 SID/Service Name、`tnsping` 測試 |
| ORA-12514 / TNS:listener does not currently know of service | Service Name 錯誤 | 檢查 `listener.ora`、`tnsnames.ora`、DB `service_names` 參數 |
| ORA-01017: invalid username/password | 認證失敗、大小寫敏感 (11g+) | 確認用戶存在、`SELECT * FROM dba_users`、密碼大小寫 |
| ClassNotFoundException: OracleDriver | 驅動 jar 不在 classpath | Tomcat: `$CATALINA_HOME/lib`;War: `WEB-INF/lib`;Maven 依賴 scope=provided |
| 中文亂碼 | 字符集不匹配 | JSP `pageEncoding="UTF-8"`、DB `NLS_CHARACTERSET=AL32UTF8`、JDBC URL 無需額外參數 |
複製 `ojdbc8.jar` 至 `$CATALINA_HOME/lib/`
context.xml 或 `
web.xml 宣告
Oracle DataSource
jdbc/oracle
javax.sql.DataSource
Container
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/oracle");
try (Connection conn = ds.getConnection()) {
// 業務邏輯
}
JSP 直連適合快速驗證,生產系統必須使用容器管理資料源 + 連線池 + 分層架構。Oracle Thin 驅動部署簡單、跨平台,配合正確的連線字串 (Service Name)、字符集 (AL32UTF8)、連線池參數調優,可滿足高併發企業級應用需求。理解 JDBC 連線生命週期、Statement/ResultSet 類型選擇、資源釋放模式,是排查資料庫交互問題的基石。