JDBC 是 Java 訪問關係數據庫的標準 API。本文詳細講解連接 Oracle 與 SQL Server 的驅動依賴、JDBC URL 格式、連接參數、連接池配置 (HikariCP)、事務控制、預編譯語句防注入、結果集處理等全鏈路實戰要點。
<!-- Oracle 19c/21c -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<version>23.4.0.0</version>
</dependency>
<!-- SQL Server (Microsoft 官方驅動) -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.4.2.jre11</version>
</dependency>
<!-- 連接池 HikariCP (高性能首選) -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
| 數據庫 | URL 模板 | 關鍵參數 |
|---|---|---|
| Oracle (Thin) | jdbc:oracle:thin:@//host:port/service_name | 服務名優於 SID;支援 TNS 別名 |
| Oracle (TNS) | jdbc:oracle:thin:@(description=(address=(host=...)(port=...))(connect_data=(service_name=...))) | 無需 tnsnames.ora |
| SQL Server | jdbc:sqlserver://host:port;databaseName=xxx;encrypt=true;trustServerCertificate=true | encrypt=true 開啟 TLS;trustServerCertificate=true 跳過憑證驗證 (開發環境) |
| SQL Server (Named Instance) | jdbc:sqlserver://host;instanceName=INST1;databaseName=xxx | 動態端口由 SQL Browser 解析 |
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:oracle:thin:@//192.168.1.100:1521/ORCL");
config.setUsername("app_user");
config.setPassword("secret");
// 核心池大小 = CPU核心數 * 2 + 1 (經驗值)
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
config.setConnectionTimeout(30000); // 30s 獲取連接超時
config.setIdleTimeout(600000); // 10min 空閒回收
config.setMaxLifetime(1800000); // 30min 最大存活
config.setConnectionTestQuery("SELECT 1 FROM DUAL"); // Oracle 驗證語句
config.setPoolName("OraclePool");
HikariDataSource ds = new HikariDataSource(config);
// 使用
try (Connection conn = ds.getConnection()) {
// 業務邏輯
} // 自動歸還連接池
String sql = "SELECT id, username, email FROM users WHERE status = ? AND create_time > ?";
try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, 1);
ps.setTimestamp(2, Timestamp.valueOf("2024-01-01 00:00:00"));
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getLong("id") + " | " + rs.getString("username"));
}
}
}
Connection conn = ds.getConnection();
try {
conn.setAutoCommit(false);
// 多條 DML
try (PreparedStatement ps1 = conn.prepareStatement("UPDATE account SET balance = balance - ? WHERE id = ?");
PreparedStatement ps2 = conn.prepareStatement("UPDATE account SET balance = balance + ? WHERE id = ?")) {
ps1.setBigDecimal(1, new BigDecimal("100.00")); ps1.setLong(2, 1L); ps1.executeUpdate();
ps2.setBigDecimal(1, new BigDecimal("100.00")); ps2.setLong(2, 2L); ps2.executeUpdate();
}
conn.commit();
} catch (Exception e) {
conn.rollback();
throw e;
} finally {
conn.setAutoCommit(true);
conn.close();
}
String sql = "INSERT INTO log (msg, level) VALUES (?, ?)";
try (Connection conn = ds.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
conn.setAutoCommit(false);
for (int i = 0; i < 10000; i++) {
ps.setString(1, "log message " + i);
ps.setString(2, "INFO");
ps.addBatch();
if (i % 1000 == 0) ps.executeBatch(); // 分批提交
}
ps.executeBatch();
conn.commit();
}
| Java 類型 | Oracle | SQL Server | set/get 方法 |
|---|---|---|---|
| String | VARCHAR2 / NVARCHAR2 | NVARCHAR / VARCHAR | setString / getString |
| Long / long | NUMBER(19) | BIGINT | setLong / getLong |
| BigDecimal | NUMBER(p,s) | DECIMAL(p,s) | setBigDecimal / getBigDecimal |
| java.sql.Date | DATE (無時間) | DATE | setDate / getDate |
| java.sql.Timestamp | TIMESTAMP / DATE | DATETIME / DATETIME2 | setTimestamp / getTimestamp |
| byte[] | BLOB / RAW | VARBINARY / IMAGE | setBytes / getBytes |
| Clob / Blob | CLOB / BLOB | VARCHAR(MAX) / VARBINARY(MAX) | setClob/setBlob / getClob/getBlob |
-Duser.timezone=GMT+8 或連接屬性 oracle.jdbc.timezoneAsRegion=false。trustServerCertificate=true;生產需導入 CA 憑證。ResultSet/Statement/Connection 必須在 finally 或 try-with-resources 中關閉。getString() 一次性載入內存。config.setLeakDetectionThreshold(30000) 檢測長時間未歸還連接。JDBC 雖屬底層 API,但掌握「驅動選型 → URL 參數 → 連接池調優 → 預編譯防注入 → 事務邊界 → 資源關閉」六步曲,即可構建高性能、安全穩定的數據訪問層。建議新項目直接使用 Spring Data JPA / MyBatis 等 ORM 框架封裝 JDBC 細節,專注業務建模;遇到複雜報表、批量導入等場景再直接操作 JDBC 發揮極致性能。