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

JDBC 資料庫操作封裝:可重用的 DatabaseBean 設計與實現

     編輯:Java 相關知識

設計目標

在 MVC 架構的控制器組件中,頻繁進行資料庫連線、增刪改查。將 JDBC 樣板碼封裝為 DatabaseBean,提供:

  • JNDI DataSource 連線池管理
  • PreparedStatement 預編譯支援(防 SQL 注入)
  • 統一的更新/查詢/事務控制/資源關閉介面

完整實現代碼

package com.newland.nlie.highway.pub_com;

import java.sql.*;
import javax.naming.Context;
import javax.sql.DataSource;

public class DatabaseBean {
    private Connection conn = null;
    private Statement stmt = null;

    /** 私有建構子,建議搭配單例或依賴注入使用 */
    public DatabaseBean() {}

    /** 透過 JNDI 取得 DataSource 建立連線 */
    private void buildConnection() throws Exception {
        try {
            Context ctx = InitBean.getInitContext(); // 專案自有工具類
            // JBoss 環境
            Object obj = ctx.lookup("java:OracleDS");
            // WebSphere 環境
            // Object obj = ctx.lookup("Pub_DataSource");
            DataSource ds = (DataSource) obj;
            this.conn = ds.getConnection();
            this.stmt = conn.createStatement();
        } catch (Exception ex) {
            throw new Exception("資料庫連線失敗", ex);
        }
    }

    /** 取得 PreparedStatement */
    public PreparedStatement getPreparedStatement(String sql) throws Exception {
        if (conn == null) buildConnection();
        return conn.prepareStatement(sql);
    }

    /** 執行更新 */
    public void executeUpdate(String sql) throws Exception {
        if (conn == null) buildConnection();
        stmt.executeUpdate(sql);
    }

    /** 執行查詢 */
    public ResultSet executeQuery(String sql) throws Exception {
        if (conn == null) buildConnection();
        return stmt.executeQuery(sql);
    }

    /** 設定自動提交 */
    public void setAutoCommit(boolean autoCommit) throws Exception {
        if (conn == null) buildConnection();
        conn.setAutoCommit(autoCommit);
    }

    /** 回滾 */
    public boolean rollback() {
        try {
            if (conn != null && !conn.getAutoCommit()) {
                conn.rollback();
            }
            return true;
        } catch (SQLException ex) {
            return false;
        }
    }

    /** 關閉資源 */
    public void close() {
        try {
            if (stmt != null) stmt.close();
            if (conn != null && !conn.isClosed()) conn.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
}

控制器中使用範例

public class UserController {
    public void addUser(User user) {
        DatabaseBean db = new DatabaseBean();
        try {
            db.setAutoCommit(false);
            String sql = "INSERT INTO users(id, name, pwd) VALUES (?, ?, ?)";
            PreparedStatement ps = db.getPreparedStatement(sql);
            ps.setString(1, user.getId());
            ps.setString(2, user.getName());
            ps.setString(3, user.getPwd());
            ps.executeUpdate();
            db.setAutoCommit(true); // 隱含 commit
        } catch (Exception e) {
            db.rollback();
            throw new RuntimeException(e);
        } finally {
            db.close();
        }
    }

    public List<User> listUsers() {
        DatabaseBean db = new DatabaseBean();
        List<User> list = new ArrayList<>();
        try {
            ResultSet rs = db.executeQuery("SELECT * FROM users");
            while (rs.next()) {
                User u = new User();
                u.setId(rs.getString("id"));
                u.setName(rs.getString("name"));
                list.add(u);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            db.close();
        }
        return list;
    }
}

改進建議(生產級)

問題改進方向
每次操作 new DatabaseBean,連線池利用率低改為 ThreadLocal 綁定連線、或 Spring JdbcTemplate/DataSourceTransactionManager 托管
ResultSet 游標在 db.close() 後失效查詢結果在 finally 前轉為 List/DTO 返回,避免外層持有關閉的 ResultSet
SQL 硬編碼分散採用 MyBatis/JPA 將 SQL 外部化至 XML/Annotation
例外處理吞噬堆疊拋出自訂 DaoException 包裝原始異常,保留堆疊
無連線洩漏偵測整合 HikariCP + leakDetectionThreshold

總結

DatabaseBean 示範了 JDBC 基礎封裝的核心要素:連線池、預編譯、事務邊界、資源確定性釋放。實務專案建議直接採用成熟框架,但理解其內部運作有助於排查連線洩漏、死鎖、SQL 注入等經典問題。

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