首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

JDBC 連接 MySQL 進階實戰(二):DBUtility 封裝連接獲取與關閉

     編輯:MySQL 綜合教學

JDBC 連接 MySQL 進階實戰(二):DBUtility 封裝連接獲取與關閉

上一節實現了基礎 JDBC 連接查詢,但存在硬編碼配置、資源釋放繁瑣、異常處理分散等問題。本節引入 DBUtility 工具類,實現配置外部化、連接獲取/關閉統一封裝、資源安全釋放,為後續連接池引入奠基。

一、外部化配置:db.properties

# src/main/resources/db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/emp?useUnicode=true&characterEncoding=utf8
jdbc.user=wonderq
jdbc.password=root

優勢:環境差異化配置(dev/test/prod)無需改代碼,僅替換文件;敏感信息可接入配置中心加密管理。

二、DBUtility 核心實現

package dao;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class DBUtility {
    private static String driver;
    private static String url;
    private static String user;
    private static String password;

    // 靜態塊:類加載時一次性讀取配置、註冊驅動
    static {
        Properties props = new Properties();
        try (InputStream is = DBUtility.class.getClassLoader().getResourceAsStream("db.properties")) {
            if (is == null) throw new RuntimeException("db.properties not found in classpath");
            props.load(is);
            driver = props.getProperty("jdbc.driver");
            url = props.getProperty("jdbc.url");
            user = props.getProperty("jdbc.user");
            password = props.getProperty("jdbc.password");
            Class.forName(driver);  // 註冊驅動
        } catch (IOException | ClassNotFoundException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    // 獲取新連接
    public static Connection openConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    // 安全關閉連接(吞掉異常,記錄日誌)
    public static void closeConnection(Connection conn) {
        if (conn != null) {
            try { conn.close(); } catch (SQLException e) { System.err.println("關閉連接異常: " + e.getMessage()); }
        }
    }

    // 通用資源關閉(ResultSet -> Statement -> Connection)
    public static void closeAll(java.sql.ResultSet rs, java.sql.Statement stmt, Connection conn) {
        if (rs != null) try { rs.close(); } catch (SQLException e) { /* ignore */ }
        if (stmt != null) try { stmt.close(); } catch (SQLException e) { /* ignore */ }
        closeConnection(conn);
    }
}

三、重構 EmpDAO:使用 DBUtility

package dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class EmpDAO {
    public void findAll() {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            conn = DBUtility.openConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery("SELECT empno, ename, sal, hiredate FROM emp");

            while (rs.next()) {
                System.out.printf("%d, %s, %.2f, %s%n",
                    rs.getInt("empno"),
                    rs.getString("ename"),
                    rs.getDouble("sal"),
                    rs.getDate("hiredate"));
            }
        } catch (SQLException e) {
            throw new RuntimeException("數據庫訪問異常", e);
        } finally {
            DBUtility.closeAll(rs, stmt, conn);  // 一鍵安全釋放
        }
    }

    public static void main(String[] args) {
        new EmpDAO().findAll();
    }
}

四、運行效果驗證

7369, SMITH, 800.00, 1980-12-17
7499, ALLEN, 1600.00, 1981-02-20
7521, WARD, 1250.00, 1981-02-22
7566, JONES, 2975.00, 1981-04-02
7654, MARTIN, 1250.00, 1981-09-28
7698, BLAKE, 2850.00, 1981-05-01
7782, CLARK, 2450.00, 1981-06-09
7788, SCOTT, 3000.00, 1987-04-19
7839, KING, 5000.00, 1981-11-17
7844, TURNER, 1500.00, 1981-09-08
7876, ADAMS, 1100.00, 1987-05-23
7900, JAMES, 950.00, 1981-12-03
7902, FORD, 3000.00, 1981-12-03
7934, MILLER, 1300.00, 1982-01-23

五、設計模式總結

模式要素體現位置
工廠模式openConnection() 封裝連接創建細節
單例/靜態工具DBUtility 無狀態,靜態方法全局可用
資源獲取即初始化 (RAII)closeAll() 在 finally 統一釋放,防洩漏
配置解耦Properties 文件外部化,支援多環境部署

六、遺留問題與下一步

  • 頻繁創建/銷毀連接開銷大:高併發下性能瓶頸明顯。
  • 連接數無上限:可能耗盡數據庫 max_connections 導致服務不可用。
  • 無連接復用機制:每次請求新建 TCP 握手、認證、分配會話資源。

👉 下一節將引入 Apache DBCP 連接池,徹底解決上述問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved