1.MFC ODBC數據庫簡述
開放數據互連(Open Database Connectivity,簡稱ODBC)是一種數據庫的互操作平臺,通過經嚴格定義的各個級別的ODBC接口和客戶系統的初始裝置,能夠為應用程序提供數據庫類型透明性和位置透明性,讓應用程序的編寫者避免了與數據源相聯的復雜性。MFC的數據庫擴展部分封裝了使用ODBC數據資源的細節,應用程序可以直接使用MFC中的數據庫擴展類,來操縱ODBC驅動程序管理器,訪問數據庫。進行MFC ODBC數據庫開發時,所需的基礎工具就是MFC ODBC數據庫類的使用。利用MFC ODBC開發就是利用MFC ODBC數據庫類來操縱ODBC數據源。Visual C++的大多數ODBC訪問是通過MFC來完成的。Visual C++的MFC類庫定義了幾個數據庫類,在利用MFC編程時常常用到,它們是CDatabase(數據庫類)、CRecordSet(記錄集類)、和CRecordView(可視記錄集類)。對于MFC ODBC數據庫類來說,CDatabase類對象表示一個同數據源的連接,通過它可以對數據源進行操作。而CRecordSet對象代表從數據源中選擇的一組記錄的集合,也就是通常所說的記錄集對象。CRecordSet對象通常用于兩種形式:動態集(dynasets)和快照集(snapshots)。動態集能與其他用戶所做的更改保持同步,快照集則是數據的一個靜態視圖。每一種形式在記錄被打開時都提供一組記錄,區別在于,當用戶在一個動態集里滾動到一條記錄時,有其他用戶或是應用程序中的其他記錄集所做的更改就會相應地顯示出來。CRecordView類對象能以控制的形式顯示數據庫記錄。這個視圖是直接連接到一個CRecordSet對象的表視圖。
2.一個應用實例
本實例是某項目中的一部分,目的是實現MFC ODBC數據庫與Access數據表格之間的相互操作。包括用Visual C++中的MFC ODBC技術實現對Access數據表格的內容的顯示、添加、修改和刪除的功能。
2.1 ODBC數據源的創建
筆者使用的操作系統為Windows XP,工具是Visual C++6.0。此例中建立的Access表格取名為“plc”。
在“控制面板”中雙擊“管理工具”圖標,然后在新出現的窗口中雙擊“數據源(ODBC)”,在彈出的對話框中選中“用戶DSN”中的“dBASE Files”,單擊“添加”按鈕,從彈出的對話框中選中“Microsoft Access Driver(*.mdb)”。單擊“完成”后,將彈出一個新的對話框,在數據源名及說明后的編輯框中填入表格名“plc”。
在命名數據源之后,需要把它連接到一個數據庫。單擊“選擇”,如圖1所示,得到存儲在數據目錄中plc.mdb的拷貝文件,選中之,單擊“確定”關閉此對話框。然后單擊“確定”,完成數據源的創建。
2.2 使用AppWizard創建一個數據庫應用程序
筆者開始從AppWizard開始創建一個新的MFC AppWizard(exe)項目。命名為Jh,然后遵從以下步驟:
1)在MFC AppWizard第一步對話框中,選擇“單個文檔”。
2)在MFC AppWizard第二步對話框中,選擇“查看數據庫不使用文件支持”,再單擊“Data Source”。
3)在RecordSet Type組框中,選擇Dynaset。在Data Source組框中,單擊ODBC單選按鈕,然后從下拉列表中選擇plc,如圖2所示,單擊ok,在彈出的新的對話框中選中message,即為本項目所要操作的表。
以后幾步接收缺省值,單擊“完成”即可。至此,已創建一個應用程序,并且在程序中自行生成一個數據源和數據源中的一個表的相關程序,其程序清單如下:
class CJhSet : public Crecordset//基于CRecordset的CjhSet新類
{
public:
CJhSet(CDatabase* pDatabase = NULL);
DECLARE_DYNAMIC(CJhSet)
// Field/Param Data
//{{AFX_FIELD(CJhSet, CRecordset)
//對應表中一些被綁定字段的變量
CString m_baudrate;
CString m_type;
CString m_unit;
CString m_number;
CString m_address;
CString m_istart;
CString m_iend;
CString m_ostart;
CString m_oend;
//}}AFX_FIELD
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CJhSet)
public:
virtual CString GetDefaultConnect(); // 返回被連接的數據源名稱
virtual CString GetDefaultSQL(); // 返回數據源中所選表名稱
virtual void DoFieldExchange(CFieldExchange* pFX); // RFX support
//}}AFX_VIRTUAL
// Implementation
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif};
2.3 實現程序的顯示記錄的功能
一旦AppWizard完成編寫這些文件,它將啟動對話框編輯器,這樣就可以設計自己的表單了。CRecordView應用程序圍繞著充當應用程序主窗口的對話框而創建。筆者也將使用像表單一樣的對話框來顯示存儲在plc數據庫記錄域中的值。如圖3所示來放置靜態文本框與編輯文本框。
CJHSet類的成員變量如圖4所示。所有的變量均為CString對象。由AppWizard創建的每個變量的類型一般與相應數據庫域的類型相似。除了創建成員變量,AppWizard還編寫了一組數據交換函數——類似于對話框的DDX函數——來在用來顯示信息的控件與定義于CRecordSet類中的數據庫域之間交換信息。
為了實現數據傳輸,就要把每個控件與代表數據庫域的CJHSet變量聯系起來。筆者通過使用CJHView來成員變量m_pSet來指向應用程序的CJHSet對象。選擇每個資源ID(筆者這里未修改編輯框的默認ID),并單擊Add Variable,從下拉表中直接選擇相應的成員變量名。全部設置好之后單擊OK,至此,運行程序,就可以實現簡單的與數據庫之間的數據顯示功能。
2.4 實現程序的添加、修改和刪除記錄的功能。
在實現上述功能之前,需要按“插入->資源->DIALOG->新建”建立一個新的對話框(與圖1所示對話框類似),以建立添加、修改的對象。并為此對話框建立一個基于CDialog基礎類的新的類CAddDlg。其ID為IDD_DIALOG1。
然后在JhView.cpp中加“#include "AddDlg.h"”,并為“添加記錄(IDC_ADD)”鍵編寫程序代碼如下。其中已經作了詳細的注解。
void CJhView::OnAdd()
{
//建立一個新的添加對話框
CAddDlg dlg;
if(dlg.DoModal()==IDOK)
{
//增加一條新的記錄
m_pSet->AddNew();
//把對話框中的記錄傳遞到記錄集中
m_pSet->m_baudrate=dlg.m_br;
m_pSet->m_type=dlg.m_ty;
m_pSet->m_unit=dlg.m_un;
m_pSet->m_number=dlg.m_nu;
m_pSet->m_address=dlg.m_add;
m_pSet->m_istart=dlg.m_is;
m_pSet->m_iend=dlg.m_ie;
m_pSet->m_ostart=dlg.m_os;
m_pSet->m_oend=dlg.m_oe;
m_pSet->Update(); //把新的記錄存在數據源里
m_pSet->MoveLast(); //指定當前記錄為最后一條記錄
UpdateData(false); //清空已輸入內容
}
}
添加記錄部分,應該先讀出當前的記錄,使其顯示在添加/修改對話框中,即:
dlg.m_br=m_pSet->m_baudrate;
dlg.m_ty=m_pSet->m_type;
dlg.m_un=m_pSet->m_unit;
dlg.m_nu=m_pSet->m_number;
dlg.m_add=m_pSet->m_address;
dlg.m_is=m_pSet->m_istart;
dlg.m_ie=m_pSet->m_iend;
dlg.m_os=m_pSet->m_ostart;
dlg.m_oe=m_pSet->m_oend;
余下的與添加記錄代碼相同,除了不要定位“m_pSet->MoveLast();”而已。
刪除記錄只是需要使用Delete()成員函數刪除當前記錄之后移到下一個記錄即可。程序清單如下:
void CJhView::OnDel()
{
try//試著刪除一條記錄
{
m_pSet->Delete();
}
catch(CDBException*error)
{
AfxMessageBox(error->m_strError);
error->Delete();
m_pSet->MoveFirst();
UpdateData(FALSE);
return;
}
//移到下一個記錄
m_pSet->MoveNext();
//測試是否為文件末尾,是,則使用MoveLast(),而不是使用MoveNext()
if(m_pSet->IsEOF())
m_pSet->MoveLast();
UpdateData(FALSE);
}
對多個記錄集的操作與對單個記錄集的操作類似,只是增加了CRecordSet類的派生類。
2.5 結束語
MFC ODBC讓開發人員僅僅使用很少的代碼就可以完成復雜的數據庫訪問,并可以對數據庫中的內容方便的實現添加、修改、刪除等操作,從而極大地減少了軟件開發的工作量,縮短了開發周期,提高了效率。而且MFC ODBC簡單易學,能實現大部分ODBC API函數的功能,所以了解和掌握MFC ODBC技術,將會給大型數據庫應用軟件帶來清晰、快捷、方便等功能。本文中的實例已經在Visual C++6.0環境下調試通過。
參考文獻:
【1】 李閩溟等著,Visual C++6.0數據庫系統開發實例導航,人民郵電出版社,2002.10
【2】 (美)Stephen D.Gilbert等著,跟我學Visual C++6.0,機械工業出版社,1999.4