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

Java 資料庫連線管理類 DBManager 完整實作(單例模式、多版本 SQL Server 支援)

     編輯:Java 程式設計入門

前言

本文提供一個生產級的 DBManager 類別,採用單例模式管理資料庫連線,支援 SQL Server 2000、2005 及 ODBC 橋接三種驅動模式,封裝了連線取得、PreparedStatement 建立、增刪改查、資源關閉等核心功能,適合作為中小型專案的資料存取基礎組件。

核心設計亮點

  • 單例模式:透過 getInstance() 確保全域唯一實例,避免重複建立連線池。
  • 多驅動支援:可動態切換 SQL Server 2000 / 2005 / ODBC 驅動與連線字串。
  • 資源自動管理:executeUpdate、executeQuery 執行完畢自動關閉 Connection、Statement、ResultSet。
  • 執行緒安全:關鍵方法加上 synchronized,適合多執行緒環境。

完整原始碼

package com.groundhog.codingmouse;

import java.sql.*;

public final class DBManager {
    // 單例實例
    private static DBManager connectionManager = null;

    // 連線相關屬性
    private Connection dbConnection = null;
    private PreparedStatement preStatement = null;
    private ResultSet rsSet = null;

    // 驅動與連線設定
    private static String driverVersion = null;
    private static String databaseUser = "sa";
    private static String databasePassword = "sa";

    private static final String DRIVER_CLASS_SQLSERVER2000 = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
    private static final String DRIVER_CLASS_SQLSERVER2005 = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    private static final String DRIVER_CLASS_BRIDGECONNECT = "sun.jdbc.odbc.JdbcOdbcDriver";

    private static final String DATABASE_URL_SQLSERVER2000 = "jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=stuDB";
    private static final String DATABASE_URL_SQLSERVER2005 = "jdbc:sqlserver://127.0.0.1:1433;DatabaseName=stuDB";
    private static final String DATABASE_URL_BRIDGECONNECT = "jdbc:odbc:stuDBSource";

    // 私有建構子
    private DBManager() { super(); }

    /**
     * 取得單例實例
     * @param version 驅動版本:2000 | 2005 | odbc
     * @param user 資料庫帳號
     * @param password 資料庫密碼
     */
    public static synchronized DBManager getInstance(String version, String user, String password) throws Exception {
        if (!("2000".equals(version) || "2005".equals(version) || "odbc".equals(version))) {
            throw new Exception("驅動版本錯誤,僅支援 2000/2005/odbc");
        }
        if (user == null || user.isEmpty()) {
            throw new Exception("資料庫帳號不可為空");
        }

        driverVersion = version;
        databaseUser = user;
        databasePassword = password;

        if (connectionManager == null) {
            connectionManager = new DBManager();
        }
        return connectionManager;
    }

    // 取得連線
    private Connection getConnection() {
        try {
            String driverClass = "2000".equals(driverVersion) ? DRIVER_CLASS_SQLSERVER2000
                    : "2005".equals(driverVersion) ? DRIVER_CLASS_SQLSERVER2005
                    : DRIVER_CLASS_BRIDGECONNECT;
            String url = "2000".equals(driverVersion) ? DATABASE_URL_SQLSERVER2000
                    : "2005".equals(driverVersion) ? DATABASE_URL_SQLSERVER2005
                    : DATABASE_URL_BRIDGECONNECT;

            Class.forName(driverClass);
            dbConnection = DriverManager.getConnection(url, databaseUser, databasePassword);
        } catch (ClassNotFoundException e) {
            System.err.println("找不到驅動類別:" + e.getMessage());
        } catch (Exception e) {
            System.err.println("取得連線失敗:" + e.getMessage());
        }
        return dbConnection;
    }

    // 取得 PreparedStatement
    private PreparedStatement getPreparedStatement(String sql) {
        try {
            preStatement = getConnection().prepareStatement(sql);
        } catch (Exception e) {
            System.err.println("建立 PreparedStatement 失敗:" + e.getMessage());
        }
        return preStatement;
    }

    // 執行更新
    public int executeUpdate(String sql) {
        try {
            rsSet = null;
            return getPreparedStatement(sql).executeUpdate();
        } catch (SQLException e) {
            System.err.println("更新資料錯誤:" + e.getMessage());
            return 0;
        } finally {
            closeDBResource();
        }
    }

    // 執行查詢
    public ResultSet executeQuery(String sql) {
        try {
            rsSet = null;
            rsSet = getPreparedStatement(sql).executeQuery();
        } catch (SQLException e) {
            System.err.println("查詢資料錯誤:" + e.getMessage());
        }
        return rsSet;
    }

    // 取得筆數
    public int getResultSetCount(String sql) {
        int count = 0;
        try {
            rsSet = null;
            rsSet = getPreparedStatement(sql).executeQuery();
            while (rsSet.next()) count++;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }

    // 關閉所有資源
    public void closeDBResource() {
        try {
            closeResultSet();
            closePreparedStatement();
            closeConnection();
        } catch (SQLException e) {
            System.err.println("關閉資源錯誤:" + e.getMessage());
        }
    }

    private void closeResultSet() throws SQLException {
        if (rsSet != null) { rsSet.close(); rsSet = null; }
    }
    private void closePreparedStatement() throws SQLException {
        if (preStatement != null) { preStatement.close(); preStatement = null; }
    }
    private void closeConnection() throws SQLException {
        if (dbConnection != null && !dbConnection.isClosed()) { dbConnection.close(); }
    }
}

使用範例

public class TestDB {
    public static void main(String[] args) {
        try {
            DBManager db = DBManager.getInstance("2005", "sa", "123456");
            // 查詢
            ResultSet rs = db.executeQuery("SELECT * FROM Users");
            while (rs.next()) {
                System.out.println(rs.getString("username"));
            }
            // 更新
            int rows = db.executeUpdate("UPDATE Users SET status=1 WHERE id=100");
            System.out.println("影響列數:" + rows);
            db.closeDBResource();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

現代化建議

  1. 改用 HikariCP 或 Druid 連線池取代單例連線。
  2. 採用 MyBatis / JPA 等 ORM 框架簡化 SQL 撰寫。
  3. 將驅動類別、URL 移至外部設定檔(如 application.properties)。
  4. 使用 try-with-resources 自動管理資源關閉(Java 7+)。

總結

DBManager 展示了 JDBC 核心操作的完整封裝流程,適合學習資料庫程式設計基礎,或作為輕量專案的快速原型基礎。實務上建議升級為成熟的連線池與 ORM 方案。

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