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

JDBC 分層架構實戰:財務帳號 DAO 設計模式與持久層最佳實踐

     編輯:MySQL 綜合教學

JDBC 分層架構實戰:財務帳號 DAO 設計模式與持久層最佳實踐

企業級應用普遍採用「表現層 + 控制層 + 業務層 + **持久層 (DAO)** + 數據源」分層架構。本文闡述 DAO (Data Access Object) 模式核心思想、職責邊界、事務控制分層策略,並給出財務帳號管理的 DAO 接口設計規範。

DAO 模式核心價值

  • 封裝數據訪問細節:連接獲取、SQL 構建/執行、結果集映射、資源關閉、異常轉換,對上層業務透明。
  • 解耦業務邏輯與數據存儲:業務層面向接口編程,不依賴具體 SQL、表結構、數據庫類型,便於單元測試 (Mock DAO) 與遷移 (MySQL → Oracle/PostgreSQL)。
  • 複用與組合:簡單業務調用單個 DAO 方法;複雜業務在 Service 層組合多個 DAO 方法,**事務邊界在 Service 層控制**,而非 DAO 內部,保證 DAO 粒度可複用。

分層職責劃分

層次職責事務控制
表現層 (Controller)HTTP 請求接收、參數校驗、視圖渲染/JSON 返回無
業務層 (Service)核心業務規則、流程編排、多 DAO 組合、**事務邊界管理** (@Transactional)統一控制
持久层 (DAO)單表/關聯表 CRUD、SQL 執行、實體映射、異常捕獲轉換為非檢查異常不控制 (無 @Transactional)
數據源連接池 (HikariCP)、數據庫實例無

財務帳號 DAO 接口設計規範

public interface FinanceAccountDao {
    // 1. 新增財務帳號
    long insert(FinanceAccount account);

    // 2. 修改帳號基本信息 (除狀態外)
    int updateInfo(FinanceAccount account);

    // 3. 修改帳號狀態 (啟用/停用/凍結)
    int updateStatus(Long accountId, AccountStatus status);

    // 4. 查詢所有帳號 (分頁)
    List<FinanceAccount> selectPage(int pageNum, int pageSize);

    // 5. 根據 ID 查詢帳號詳情
    FinanceAccount selectById(Long accountId);

    // 6. 根據條件動態查詢 (可選)
    List<FinanceAccount> selectByCondition(FinanceAccountQuery query);
}

關鍵實現要點

  1. 實體類:FinanceAccount 包含 id、account_no、account_name、balance、status、create_time、update_time 等字段,對應表列。
  2. 動態 SQL 構建:更新方法僅更新非空字段 (MyBatis `` / 手動拼接),避免全列更新覆蓋並發修改。
  3. 異常轉換:捕獲 SQLException,包裝為 DaoException (RuntimeException) 拋出,Service 層統一處理。
  4. 連接管理:從 ThreadLocal / Spring 管理的事務連接獲取 Connection,**不在 DAO 中開啟/提交/關閉事務**。
  5. 分頁實現:MySQL LIMIT ?, ? + COUNT(*) 統計總數;大偏移量優化採用「游標/ID 下標」模式。

事務控制反模式與正確姿勢

❌ 錯誤:在 DAO 方法內部 con.setAutoCommit(false) / commit()。導致:多 DAO 組合時無法保證原子性、DAO 無法複用、連接洩漏風險。

✅ 正確:Service 方法加 @Transactional (Spring) 或手動控制 Connection 事務,調用多個 DAO 方法:

@Transactional
public void transfer(Long fromId, Long toId, BigDecimal amount) {
    FinanceAccount from = dao.selectById(fromId);
    FinanceAccount to = dao.selectById(toId);
    // 業務校驗...
    from.setBalance(from.getBalance().subtract(amount));
    to.setBalance(to.getBalance().add(amount));
    dao.updateInfo(from); // 同一事務
    dao.updateInfo(to);   // 同一事務
}

總結

DAO 是持久層的「門面」,職責單一:SQL 執行與對象映射。事務、緩存、鎖、幂等性等橫切關注點屬於 Service 或基礎設施層。良好的分層讓代碼可測、可維、可擴展。

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