首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

CDataSet:強化 MFC 資料庫開發的模板記錄集類別

     編輯:關於VC++

MFC 的 CDatabase 和 CRecordset 類別雖然功能完整,但在處理多資料表應用時,類別精靈會產生大量記錄集原始碼檔案,導致專案結構臃腫混亂。本文介紹的 CDataSet 模板類別,旨在減少程式碼數量,同時增強記錄集功能,為資料物件陣列提供統一介面。

CDataSet 類別設計

CDataSet 採用雙參數模板設計:

  • 資料物件類別 (T):對應資料表欄位的結構或類別
  • 綁定欄位數量 (M):指定欄位總數
template <class T, int M>
class CDataSet : public CRecordset {
public:
    CDataSet(LPCSTR Table, CDatabase* pdb);
    T m_Data;                    // 連結的資料物件
    CString m_DefaultSQL;        // 預設 SQL SELECT 陳述式
    CString m_DefaultSort;       // 預設 ORDER BY 子句
    CString m_DefaultFilter;     // 預設 WHERE 子句
    
    // 核心操作方法
    virtual BOOL Search(LPCSTR Filter, LPCSTR Sort = NULL, BOOL bFail = FALSE);
    virtual BOOL DirectSearch(LPCSTR Filter, LPCSTR Sort = NULL, BOOL bFail = FALSE);
    virtual void LoadAll(CArray<T, T>& A, int N = 0);
    virtual void SaveAll(CArray<T, T>& A);
    virtual void Load(T& Data) { Data = m_Data; }
    virtual void Store(T& Data);
    // ...
};

關鍵特性解析

靈活的 SQL 控制

m_DefaultSQL 可為資料表名、資料表清單或複雜 SQL 陳述式,且可在執行期動態修改,使相同類別能存取結構相同的不同資料表。

資料物件陣列操作

  • LoadAll():批次載入記錄至陣列,N 參數限制最大筆數
  • SaveAll():批次寫入陣列資料至資料庫
  • Load()/Store():單筆資料的載入與儲存

強化搜尋能力

  • Search():使用預設排序與篩選,找不到且 bFail=TRUE 時拋出例外
  • DirectSearch():接受外部指定的 WHERE 子句,支援動態查詢

實作細節與輔助功能

狀態列回饋機制

多數方法呼叫 SetStatus() 顯示沙漏游標與狀態列訊息,處理大量資料時特別有用:

void SetStatus(const CString Msg) {
    CFrameWnd* pMainFrame = (CFrameWnd*)AfxGetMainWnd();
    if (pMainFrame) {
        pMainFrame->SetMessageText(Msg);
        pMainFrame->UpdateWindow();
        if (strcmp(Msg, "Ready") == 0)
            pMainFrame->EndWaitCursor();
        else
            pMainFrame->BeginWaitCursor();
    }
}

自訂例外處理

CMyException 繼承自 CException,提供自訂錯誤訊息功能,配合 THROW 宏使用。

使用範例

// 定義資料物件結構
struct DataObj {
    CString Var1;
    CString Var2;
    int Var3;
    float Var4;
};

// 實作 DoFieldExchange 建立欄位對應
void CDataSet<DataObj, 4>::DoFieldExchange(CFieldExchange* pFX) {
    pFX->SetFieldType(CFieldExchange::outputColumn);
    RFX_Text(pFX, "VAR1", m_Data.Var1);
    RFX_Text(pFX, "VAR2", m_Data.Var2);
    RFX_Int(pFX, "VAR3", m_Data.Var3);
    RFX_Single(pFX, "VAR4", m_Data.Var4);
}

// 應用程式中使用
CDatabase db;
CArray<DataObj, DataObj> A;
TRY {
    db.Open("TEST");
    CDataSet<DataObj, 4> MySet("Table1", &db);
    MySet.m_DefaultFilter = "Var1 = '%s'";
    MySet.Open();
    MySet.LoadAll(A);           // 載入所有記錄
    if (MySet.Search("Anything")) { // 搜尋特定記錄
        DataObj B;
        MySet.Load(B);
        B.Var1 = "Anything else?";
        MySet.Store(B);         // 更新記錄
    }
    MySet.Close();
} CATCH_ALL(e) { e->ReportError(); } END_CATCH_ALL

總結

CDataSet 透過模板機制大幅減少樣板程式碼,統一了資料存取介面,並提供批次操作、動態 SQL、強化搜尋等實用功能,是 MFC 多資料表應用開發的有力工具。

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