首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JDBC 核心原理與實戰封裝:從 DriverManager 到連線池演進

     編輯:Java 相關知識

前言

JDBC (Java Database Connectivity) 是 Java 操作關聯式資料庫的標準 API。本文系統梳理:JDBC 本質、核心介面、標準操作流程、Oracle/MySQL 實戰、三版本封裝演進 (工具類 → Properties 配置 → 連線池)、資源管理鐵律與最佳實踐。

JDBC 本質:介面與實作分離

  • JDBC API:java.sql / javax.sql 定義的介面 (Connection、Statement、ResultSet...)。
  • JDBC Driver:各資料庫廠商實作介面的具體類別 (ojdbc.jar、mysql-connector-j.jar)。
  • DriverManager:服務定位器,根據 URL 協議載入對應 Driver 建立連線。

核心介面速查

標準操作五步驟

// 1. 載入驅動 (JDBC 4.0+ 可省略,SPI 自動發現)
Class.forName("oracle.jdbc.OracleDriver");  // 或 com.mysql.cj.jdbc.Driver

// 2. 建立連線
Connection conn = DriverManager.getConnection(
    "jdbc:oracle:thin:@//host:1521/service", "user", "pwd");

// 3. 建立 Statement / PreparedStatement
PreparedStatement ps = conn.prepareStatement(
    "INSERT INTO emp(empno, ename, sal, deptno) VALUES (?, ?, ?, ?)");

// 4. 綁定參數、執行
ps.setInt(1, 1001);
ps.setString(2, "Alice");
ps.setDouble(3, 8000);
ps.setInt(4, 10);
int rows = ps.executeUpdate();  // DML 返回影響行數

// 5. 關閉資源 (逆序、分別 try-catch、finally 保證)
ResultSet rs = null;
try { /* ... */ }
finally {
    closeQuietly(rs);
    closeQuietly(ps);
    closeQuietly(conn);
}

三版本封裝演進

V1:硬編碼工具類

public class DBUtilV1 {
    private static final String URL = "jdbc:oracle:thin:@localhost:1521:orcl";
    private static final String USER = "scott", PWD = "tiger";
    static { Class.forName("oracle.jdbc.OracleDriver"); }
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(URL, USER, PWD);
    }
    public static void close(Connection c) { /* ... */ }
}

缺點:修改配置需改代碼重編譯。

V2:Properties 外部配置

// db.properties
jdbc.driver=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@//host:1521/service
jdbc.user=scott
jdbc.password=tiger

// DBUtilV2
static {
    Properties p = new Properties();
    p.load(DBUtilV2.class.getClassLoader().getResourceAsStream("db.properties"));
    URL = p.getProperty("jdbc.url"); // ...
    Class.forName(p.getProperty("jdbc.driver"));
}

優點:配置與代碼分離,部署環境只改 properties。

V3:生產級連線池

手寫連線池易出 Bug (併發、洩漏、超時、驗證)、**強烈建議直接使用成熟連線池**:

  • HikariCP:極致效能、輕量、Spring Boot 2+ 預設。
  • Druid:阿里出品、監控強大、SQL 防火牆。
  • DBCP2 / c3p0:老牌,較少新專案採用。

HikariCP 整合範例

// application.yml (Spring Boot)
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
    username: root
    password: secret
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000

// 使用
@Autowired DataSource dataSource;
try (Connection conn = dataSource.getConnection()) { ... }

資源管理鐵律

  1. 逆序關閉:ResultSet → Statement → Connection。
  2. 分別 try-catch:單一 close 拋異常不影響後續關閉。
  3. Java 7+ try-with-resources:自動關閉實作 AutoCloseable 的資源。
try (Connection conn = ds.getConnection();
     PreparedStatement ps = conn.prepareStatement(sql);
     ResultSet rs = ps.executeQuery()) {
    while (rs.next()) { /* ... */ }
} // 自動關閉,即使拋異常

防止 SQL 注入:PreparedStatement 鐵律

// 錯誤:字串拼接
String sql = "SELECT * FROM user WHERE name = '" + name + "'";  // 注入風險

// 正確:參數化查詢
String sql = "SELECT * FROM user WHERE name = ?";
ps.setString(1, name);  // 驅動負責轉義、型別轉換

批次處理大幅提升寫入效能

conn.setAutoCommit(false);
String sql = "INSERT INTO log(ts, msg) VALUES (?, ?)";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
    for (LogEvent e : events) {
        ps.setTimestamp(1, new Timestamp(e.getTime()));
        ps.setString(2, e.getMsg());
        ps.addBatch();
        if (++count % 1000 == 0) ps.executeBatch();
    }
    ps.executeBatch();
    conn.commit();
}

總結

JDBC 是持久層基石。理解其介面設計、資源管理、連線池原理,能讓你在排查連線洩漏、調優批次寫入、選擇 ORM 框架時擁有底層視野。現代專案:拒絕手寫連線池,直接上 HikariCP/Druid。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
介面職責關鍵方法
Driver驅動註冊與連線建立connect(url, props)
Connection資料庫會話、事務控制createStatement、prepareStatement、commit、rollback、setAutoCommit
Statement靜態 SQL 執行executeQuery、executeUpdate、execute
PreparedStatement預編譯參數化 SQL (防注入)setXxx、addBatch、executeBatch
CallableStatement儲存過程/函數呼叫registerOutParameter、execute
ResultSet查詢結果游標next、getXxx、close