眾所周知,VC ++的MFC
類庫為編程者編制好了對數據庫操作的類,編程者可以使用向導建立一個與數據庫聯結并對數據庫進行操作的應用程序,不需要編制任何代碼,
這無疑為編程人員提供了一個捷徑。但是,使用向導時只有選用基于單文檔或多文檔的項目才能選擇數據源與指定的的數據庫相連,
對用向導生成的基于對話框的應用程序不提供數據庫的支持。即使是基于單文檔或多文檔的應用程序,
當需要一些特殊的操作,例如,打開一個表,要求返回滿足一定條件的記錄集時,MFC
并沒有提供完全符合要求的現成函數。如果能利用MFC
所提供的數據庫操作,再加上自己設計的函數,也就是說,設計一個對數據庫操作的類,在程序中手工加入這個類,
那么就可以在基于對話框的應用程序中實現對數據庫的操作,而且,也可以針對自己應用程序的具體需要來設計類的函數,為特定功能的實現提供了很大的方便。
在一個涉及數據庫操作的應用程序中,常用到的MFC 類有CdaoDatabase
類、CdaoTableDef 類、CdaoRecordset 類和CdaoQueryDef
類。當對數據庫進行操作時,需要先打開數據庫,然后打開數據庫中的表,再得到查詢集和記錄集。在自己定義的類中綜合這四個類的操作,設計一個打開表得到查詢集和記錄集的函數。以后,在應用程序中使用該類時只需包含該類的頭文件,所設計的函數就可以直接調用了。
建立數據庫類的過程可分為如下四步。
定義一個無基類的CdataBaseOperate 類
1.?在Workspace 窗口選擇ClassView
選項卡,在樹型類結構圖的根部單擊鼠標右鍵, 選擇New Class...,
系統將彈出建立新類的對話框;
2. lass type 中選擇Generic Class;
3. 在Name 中填寫要建的新類的名稱, 要以大寫字母C 開頭,
系統會自動建立新類的頭文件和實現文件,
文件的名稱為類名去掉第一個大寫字母C,
如果想改變文件的名稱,可以單擊change 按鈕;
4. 填寫好各項后,按OK
按鈕確定,一個無基類的新類建立成功。但他還是一個空類,下一步就要給類添加內容。
在自定義的類中加入有關的定義
1. 在本應用程序中,使用ODBC 與SQL SERVER
的數據庫相連,因而,在類的實現文件構造函數前加入如下的定義:
#define SQL_DATABASE _T
("ODBC;DSN=sql -database;UID=sa;PWD=pass;")
DSN=sql -database 表示建立的ODBC 聯接的名稱是sql -database,如果選用其他數據庫,只需在此改變與所需數據庫建立的聯接,或是重新配置sql
-database,使之聯接新的數據庫。UID=sa;PWD=pass
表示登錄數據庫的用戶名是sa,密碼是pass,如果密碼是空則表示為PWD=""。
2. 在該類中綜合使用到了MFC 類庫提供的有關數據庫的幾個類:CdaoDatabase
類、CdaoTableDef 類、CdaoRecordset 類和CdaoQueryDef
類,而這四個類的定義和實現都包括在頭文件afxdao.h
中,因此,在新定義的類的頭文件中一定要加上語句:
?。nclude <afxdao.h>;
3. 對要用到的四個類各聲明一個對象如下:
CDaoDatabase *loc_pDataBase;
CDaoTableDef *loc_pTable;
CDaoRecordset loc_pRecordset;
CDaoQueryDef *loc_pQueryDef;
其中CdaoDatabase 類、CdaoTableDef 類和CdaoQueryDef
類定義了對象指針,在使用時要先new,最后要delete。以CdaoDatabase
類為例,在CdataBaseOperate 類的構造函數中初始化對象指針loc_pDataBase=new
CDaoDatabase; 在析構函數中要釋放該指針delete loc_pDataBase。
在自定義的類中加入所需的函數和變量
手工加入函數包括兩項工作,首先在頭文件中加入函數的聲明,然后在實現文件中加入函數的具體實現,聲明與實現一定要統一。
使用向導加入函數和變量:
1、在Workspace 窗口選擇ClassView 選項卡;
2、在樹型類結構圖的要添加函數和變量的類上單擊鼠標右鍵,
如果加入成員函數則單擊Add Member Function,加入虛函數單擊Add Virtual
Function,加入成員變量單擊Add Member Variable;
3、出現對話框后,填寫成員函數或變量的名稱、類型,系統會自動添加函數的聲明與實現;
4、添加函數的具體操作,可以通過編輯代碼進一步填寫。
這些操作將會在Workspace 窗口的ClassView
選項中立即體現出來,并且單擊ClassView
中的相應函數就可進入該函數的實現部分,進一步編寫代碼。如果做不到這一點,說明添加成員函數的操作有誤。
下面以本應用程序為例,給出具體的表結構和幾個主要函數的實現,讀者可以根據自己的實際情況設計函數。
本應用程序中的一個典型表的結構是:
打開數據庫的函數實現如下:
if (!loc_pDataBase ->IsOpen())
loc_pDataBase ->Open
( NULL, FALSE, FALSE, SQL_DATABASE);
該函數中用到了CdaoDatabase 類的兩個函數IsOpen() 和Open(NULL, FALSE,
FALSE, SQL_DATABASE),因為已經聲明了該類的指針對象loc_pDataBase,所以可以直接調用CdaoDatabase
類的函數。其中Open()函數中的最后一個參數SQL_DATABASE
在前面已經介紹過,通過他打開相關的數據庫。
由于程序中打開表后,不僅要返回所有的記錄集,還用到返回滿足一定條件的記錄集,因此打開表的函數除了帶入表名外還有一個參數難度系數,lNDXS=0
時, 選擇表中全部數據, lNDXS=1 ~n 時, 表示選擇難度系數=1 ~n
的記錄。
bool CDataBaseOperate::OpenTable
(CString strTableName,long lNDXS)
{
CString strFieldNumber;
loc_pTable=new CDaoTableDef(loc_pDataBase);
if (!loc_pTable ->IsOpen())
loc_pTable ->Open(strTableName);
// 打開指定的表名
strFieldNumber.Format("%d",loc_pTable ->
GetFieldCount()); // 得到字段數
CString Sqlstr,Sqlstr1,Sqlstr2;
loc_pQueryDef=new CDaoQueryDef(loc_pDataBase);
// 得到查詢集和記錄集
if (lNDXS==0){ Sqlstr=_T
("SELECT *FROM " +strTableName);}
else{ Sqlstr1="SELECT *FROM " +strTableName
Sqlstr2.Format
(" WHERE 難度系數= %d",lNDXS);
Sqlstr=_T(Sqlstr1 +Sqlstr2); }
loc_pQueryDef ->Create(NULL,Sqlstr);
loc_pRecordset.Open(loc_pQueryDef);
m_nRecordNumber=0;
while(!loc_pRecordset.IsEOF()) {
m_nRecordNumber ++;
loc_pRecordset.MoveNext();}
return TRUE;
}
為了維護數據庫的安全,表用過后應該關閉,關閉表的同時,要釋放在打開表的操作時初始化的對象指針,例如:delete
loc_pQueryDef。同樣要注意,在構造函數中初始化的對象指針,在析構函數中一定要釋放。對象指針的初始化和釋放是成對出現的。
loc_pDataBase=new CDaoDatabase;
// 在構造函數中初始化對象指針。
delete loc_pDataBase;
// 在析構函數中釋放該對象指針。
CdataBaseOperate 類的應用
1. 使用VC
++的向導生成一個應用程序,可以根據需要選擇基于對話框或是基于單、多文檔,選擇單文檔或多文檔時不要選擇數據庫支持。
2. 在應用程序的主頭文件中加入#include "DataBaseOperate.h",并且還要聲明一個CdataBaseOperate
類的對象,public: CDataBaseOperate m_CDataBaseOperate。
3. 有了指向CdataBaseOperate 類的對象后,剛剛在CdataBaseOperate
類中編制的函數都可以通過“m_CdataBaseOperate
.函數名”來調用?! ?/p>