一、實(shí)現(xiàn)方法
DAO(Database Access Object)使用Microsoft Jet數(shù)據(jù)庫(kù)引擎來訪問數(shù)據(jù)庫(kù)。Microsoft Jet為象Access和Visual Basic這樣的產(chǎn)品都提供了該數(shù)據(jù)引擎。與ODBC一樣,DAO提供了一組API供編程使用。MFC也提供了一組DAO類,封裝了底層的API,從而大大簡(jiǎn)化了程序的開發(fā)。利用MFC的DAO類,用戶可以編寫?yīng)毩⒂贒BMS的應(yīng)用程序。
DAO是從Visual C++4.0版開始引入的。一般地講,DAO類提供了比ODBC類更廣泛的支持。一方面,只要有ODBC驅(qū)動(dòng)程序,使用Microsoft Jet的DAO就可以訪問ODBC數(shù)據(jù)源。另一方面,由于DAO是基于Microsoft Jet引擎的,因而在訪問Access數(shù)據(jù)庫(kù)(即*.MDB文件)時(shí)具有很好的性能。DAO類與ODBC類相比具有很多相似之處,這主要有下面幾點(diǎn):(1)二者都支持對(duì)各種ODBC數(shù)據(jù)源的訪問。雖然二者使用的數(shù)據(jù)引擎不同,但都可以滿足用戶編寫?yīng)毩⒂贒BMS的應(yīng)用程序的要求。(2)DAO提供了與ODBC功能相似的MFC類。例如,DAO的CDaoDatabase類對(duì)應(yīng)ODBC的CDatabase類,CDaoRecordset對(duì)應(yīng)CRecordset,CDaoRecordView對(duì)應(yīng)CRecordView,CDaoException對(duì)應(yīng)CDBException。這些對(duì)應(yīng)的類功能相似,它們的大部分成員函數(shù)都是相同的。(3)AppWizard和ClassWizard對(duì)使用DAO和ODBC對(duì)象的應(yīng)用程序提供了類似的支持。
由于DAO和ODBC類的許多方面都比較相似,因此只要用戶掌握了ODBC,就很容易學(xué)會(huì)使用DAO。實(shí)際上,用戶可以很輕松地把數(shù)據(jù)庫(kù)應(yīng)用程序從ODBC移植到DAO。需要注意的是,DAO和ODBC參數(shù)化的方式不同。DAO記錄集的m_strFilter和m_strSort中的參數(shù)不是"?"號(hào),而是一個(gè)有意義的參數(shù)名。例如,在下面的過濾器中有一個(gè)名為CourseIDParam的參數(shù)。
m_pSet->m_strFilter ="CourseID = CourseIDParam";
在DoFieldExchange函數(shù)中,有下面兩行:
pFX->SetFieldType(CDaoFieldExchange::param);
DFX_Text(pFX, _T("CourseIDParam"), m_strCourseIDParam);
DFX函數(shù)的第二個(gè)參數(shù)也是CourseIDParam。
除了上述差別外,AppWizard和ClassWizard也隱藏了一些細(xì)微的不同之處,例如,DAO記錄集是使用是DFX數(shù)據(jù)交換機(jī)制(DAO record field exchange)而不是RFX,在DAO記錄集的DoFieldExchange中使用的是DFX函數(shù)而不是RFX函數(shù)。
DAO可以通過ODBC驅(qū)動(dòng)程序訪問ODBC數(shù)據(jù)源。但DAO是基于Microsoft Jet引擎的,通過該引擎,DAO可以直接訪問Access、FoxPro、dBASE、Paradox、Excel和Lotus WK等數(shù)據(jù)庫(kù)。CDaoDatabase類可以直接與這些數(shù)據(jù)庫(kù)進(jìn)行連接,而不必在ODBC管理器中注冊(cè)DSN。例如,下面的代碼用來打開一個(gè)FoxPro數(shù)據(jù)庫(kù):
CDaoDatabase daoDb;
daoDb.Open("",FALSE,FALSE,"FoxPro 2.5;DATABASE=c:\\zyf");
CDaoDatabase::Open函數(shù)用來連接某個(gè)數(shù)據(jù)庫(kù),該函數(shù)的聲明為:
virtual void Open( LPCTSTR lpszName, BOOL bExclusive = FALSE,
BOOL bReadOnly = FALSE, LPCTSTR lpszConnect = _T("") );
throw( CDaoException, CMemoryException );
參數(shù)bExclusive如果為TRUE,則函數(shù)以獨(dú)占方式打開數(shù)據(jù)庫(kù),否則就用共享方式。如果bReadOnly為TRUE,那么就以只讀方式打開數(shù)據(jù)庫(kù)。如果要打開一個(gè)Access數(shù)據(jù)庫(kù),則可以在lpszName參數(shù)中指定MDB文件名。如果要訪問非Access數(shù)據(jù)庫(kù),則應(yīng)使該參數(shù)為"",并在lpszConnect中說明一個(gè)連接字符串。連接字符串的形式一般為 "數(shù)據(jù)庫(kù)類型;DATABASE=路徑(文件)",例如 "dBASE III;DATABASE=c:\\MYDIR"
Open()函數(shù)也可以打開一個(gè)ODBC數(shù)據(jù)源,但這需要相應(yīng)的ODBC驅(qū)動(dòng)程序,并需要在ODBC管理器中注冊(cè)DSN。此時(shí)lpszConnect的形式為 "ODBC;DSN=MyDataSource"。顯然,用DAO訪問象FoxPro這樣的數(shù)據(jù)庫(kù)時(shí),直接打開比把它當(dāng)作ODBC數(shù)據(jù)源打開要省事。
支持DDL是DAO對(duì)數(shù)據(jù)庫(kù)編程良好支持的一個(gè)重要體現(xiàn)。DDL(Data Definition Language)在SQL術(shù)語(yǔ)中叫做"數(shù)據(jù)定義語(yǔ)言",它用來完成生成、修改和刪除數(shù)據(jù)庫(kù)結(jié)構(gòu)的操作。ODBC類只支持DML(Data Manipulation Language,數(shù)據(jù)操作語(yǔ)言),不支持DDL,所以用ODBC類只能完成數(shù)據(jù)的操作,不能涉及數(shù)據(jù)庫(kù)的結(jié)構(gòu)。要執(zhí)行DDL操作,只有通過ODBC API。而DAO類同時(shí)提供了對(duì)DML和DDL的支持,這意味著程序可以使用DAO類方便的創(chuàng)建數(shù)據(jù)庫(kù)及修改數(shù)據(jù)庫(kù)的結(jié)構(gòu)。
與ODBC相比,DAO提供了一些新類來加強(qiáng)其功能,這些新類包括:CDaoTableDef類提供了對(duì)表的結(jié)構(gòu)的定義。調(diào)用CDaoTableDef::Open()函數(shù)可以獲得表的結(jié)構(gòu)定義。調(diào)用CDaoTableDef::Create()函數(shù)可以創(chuàng)建一張新表,調(diào)用CDaoTableDef:: CreateField()函數(shù)可為表添加字段,調(diào)用CDaoTableDef::CreateIndex()函數(shù)可以為表添加索引。調(diào)用CDaoTableDef::Append()函數(shù)可以把新創(chuàng)建的表保存到數(shù)據(jù)庫(kù)中。
CDaoQueryDef類代表一個(gè)查詢定義(Query definition),該定義可以被存儲(chǔ)到數(shù)據(jù)庫(kù)中。CDaoWorkspace提供了數(shù)據(jù)工作區(qū)(Workspace)。一個(gè)工作區(qū)可以包含幾個(gè)數(shù)據(jù)庫(kù),工作區(qū)可以對(duì)所屬的數(shù)據(jù)庫(kù)進(jìn)行全體或單獨(dú)的事務(wù)處理,工作區(qū)也負(fù)責(zé)數(shù)據(jù)庫(kù)的安全性。如果需要,程序可以打開多個(gè)工作區(qū)。
DAO的另一個(gè)重要特色在于它對(duì)Access數(shù)據(jù)庫(kù)提供了強(qiáng)大的支持。由于DAO是基于Microsoft Jet引擎的,所以DAO肯定要在Access數(shù)據(jù)庫(kù)上多作一些文章。例如,調(diào)用CDaoDatabase::Create()函數(shù)可以直接建立一個(gè)MDB文件,代碼如下所示:
m_db.Create("C:\\MYDIR\\MYDB.MDB");
利用AppWizard和ClassWizard,用戶可以方便地開發(fā)出性能優(yōu)良的基于DAO的Access數(shù)據(jù)庫(kù)應(yīng)用程序。
DAO(Database Access Object)使用Microsoft Jet數(shù)據(jù)庫(kù)引擎來訪問數(shù)據(jù)庫(kù)。Microsoft Jet為象Access和Visual Basic這樣的產(chǎn)品都提供了該數(shù)據(jù)引擎。與ODBC一樣,DAO提供了一組API供編程使用。MFC也提供了一組DAO類,封裝了底層的API,從而大大簡(jiǎn)化了程序的開發(fā)。利用MFC的DAO類,用戶可以編寫?yīng)毩⒂贒BMS的應(yīng)用程序。
DAO是從Visual C++4.0版開始引入的。一般地講,DAO類提供了比ODBC類更廣泛的支持。一方面,只要有ODBC驅(qū)動(dòng)程序,使用Microsoft Jet的DAO就可以訪問ODBC數(shù)據(jù)源。另一方面,由于DAO是基于Microsoft Jet引擎的,因而在訪問Access數(shù)據(jù)庫(kù)(即*.MDB文件)時(shí)具有很好的性能。DAO類與ODBC類相比具有很多相似之處,這主要有下面幾點(diǎn):(1)二者都支持對(duì)各種ODBC數(shù)據(jù)源的訪問。雖然二者使用的數(shù)據(jù)引擎不同,但都可以滿足用戶編寫?yīng)毩⒂贒BMS的應(yīng)用程序的要求。(2)DAO提供了與ODBC功能相似的MFC類。例如,DAO的CDaoDatabase類對(duì)應(yīng)ODBC的CDatabase類,CDaoRecordset對(duì)應(yīng)CRecordset,CDaoRecordView對(duì)應(yīng)CRecordView,CDaoException對(duì)應(yīng)CDBException。這些對(duì)應(yīng)的類功能相似,它們的大部分成員函數(shù)都是相同的。(3)AppWizard和ClassWizard對(duì)使用DAO和ODBC對(duì)象的應(yīng)用程序提供了類似的支持。
由于DAO和ODBC類的許多方面都比較相似,因此只要用戶掌握了ODBC,就很容易學(xué)會(huì)使用DAO。實(shí)際上,用戶可以很輕松地把數(shù)據(jù)庫(kù)應(yīng)用程序從ODBC移植到DAO。需要注意的是,DAO和ODBC參數(shù)化的方式不同。DAO記錄集的m_strFilter和m_strSort中的參數(shù)不是"?"號(hào),而是一個(gè)有意義的參數(shù)名。例如,在下面的過濾器中有一個(gè)名為CourseIDParam的參數(shù)。
m_pSet->m_strFilter ="CourseID = CourseIDParam";
在DoFieldExchange函數(shù)中,有下面兩行:
pFX->SetFieldType(CDaoFieldExchange::param);
DFX_Text(pFX, _T("CourseIDParam"), m_strCourseIDParam);
DFX函數(shù)的第二個(gè)參數(shù)也是CourseIDParam。
除了上述差別外,AppWizard和ClassWizard也隱藏了一些細(xì)微的不同之處,例如,DAO記錄集是使用是DFX數(shù)據(jù)交換機(jī)制(DAO record field exchange)而不是RFX,在DAO記錄集的DoFieldExchange中使用的是DFX函數(shù)而不是RFX函數(shù)。
DAO可以通過ODBC驅(qū)動(dòng)程序訪問ODBC數(shù)據(jù)源。但DAO是基于Microsoft Jet引擎的,通過該引擎,DAO可以直接訪問Access、FoxPro、dBASE、Paradox、Excel和Lotus WK等數(shù)據(jù)庫(kù)。CDaoDatabase類可以直接與這些數(shù)據(jù)庫(kù)進(jìn)行連接,而不必在ODBC管理器中注冊(cè)DSN。例如,下面的代碼用來打開一個(gè)FoxPro數(shù)據(jù)庫(kù):
CDaoDatabase daoDb;
daoDb.Open("",FALSE,FALSE,"FoxPro 2.5;DATABASE=c:\\zyf");
CDaoDatabase::Open函數(shù)用來連接某個(gè)數(shù)據(jù)庫(kù),該函數(shù)的聲明為:
virtual void Open( LPCTSTR lpszName, BOOL bExclusive = FALSE,
BOOL bReadOnly = FALSE, LPCTSTR lpszConnect = _T("") );
throw( CDaoException, CMemoryException );
參數(shù)bExclusive如果為TRUE,則函數(shù)以獨(dú)占方式打開數(shù)據(jù)庫(kù),否則就用共享方式。如果bReadOnly為TRUE,那么就以只讀方式打開數(shù)據(jù)庫(kù)。如果要打開一個(gè)Access數(shù)據(jù)庫(kù),則可以在lpszName參數(shù)中指定MDB文件名。如果要訪問非Access數(shù)據(jù)庫(kù),則應(yīng)使該參數(shù)為"",并在lpszConnect中說明一個(gè)連接字符串。連接字符串的形式一般為 "數(shù)據(jù)庫(kù)類型;DATABASE=路徑(文件)",例如 "dBASE III;DATABASE=c:\\MYDIR"
Open()函數(shù)也可以打開一個(gè)ODBC數(shù)據(jù)源,但這需要相應(yīng)的ODBC驅(qū)動(dòng)程序,并需要在ODBC管理器中注冊(cè)DSN。此時(shí)lpszConnect的形式為 "ODBC;DSN=MyDataSource"。顯然,用DAO訪問象FoxPro這樣的數(shù)據(jù)庫(kù)時(shí),直接打開比把它當(dāng)作ODBC數(shù)據(jù)源打開要省事。
支持DDL是DAO對(duì)數(shù)據(jù)庫(kù)編程良好支持的一個(gè)重要體現(xiàn)。DDL(Data Definition Language)在SQL術(shù)語(yǔ)中叫做"數(shù)據(jù)定義語(yǔ)言",它用來完成生成、修改和刪除數(shù)據(jù)庫(kù)結(jié)構(gòu)的操作。ODBC類只支持DML(Data Manipulation Language,數(shù)據(jù)操作語(yǔ)言),不支持DDL,所以用ODBC類只能完成數(shù)據(jù)的操作,不能涉及數(shù)據(jù)庫(kù)的結(jié)構(gòu)。要執(zhí)行DDL操作,只有通過ODBC API。而DAO類同時(shí)提供了對(duì)DML和DDL的支持,這意味著程序可以使用DAO類方便的創(chuàng)建數(shù)據(jù)庫(kù)及修改數(shù)據(jù)庫(kù)的結(jié)構(gòu)。
與ODBC相比,DAO提供了一些新類來加強(qiáng)其功能,這些新類包括:CDaoTableDef類提供了對(duì)表的結(jié)構(gòu)的定義。調(diào)用CDaoTableDef::Open()函數(shù)可以獲得表的結(jié)構(gòu)定義。調(diào)用CDaoTableDef::Create()函數(shù)可以創(chuàng)建一張新表,調(diào)用CDaoTableDef:: CreateField()函數(shù)可為表添加字段,調(diào)用CDaoTableDef::CreateIndex()函數(shù)可以為表添加索引。調(diào)用CDaoTableDef::Append()函數(shù)可以把新創(chuàng)建的表保存到數(shù)據(jù)庫(kù)中。
CDaoQueryDef類代表一個(gè)查詢定義(Query definition),該定義可以被存儲(chǔ)到數(shù)據(jù)庫(kù)中。CDaoWorkspace提供了數(shù)據(jù)工作區(qū)(Workspace)。一個(gè)工作區(qū)可以包含幾個(gè)數(shù)據(jù)庫(kù),工作區(qū)可以對(duì)所屬的數(shù)據(jù)庫(kù)進(jìn)行全體或單獨(dú)的事務(wù)處理,工作區(qū)也負(fù)責(zé)數(shù)據(jù)庫(kù)的安全性。如果需要,程序可以打開多個(gè)工作區(qū)。
DAO的另一個(gè)重要特色在于它對(duì)Access數(shù)據(jù)庫(kù)提供了強(qiáng)大的支持。由于DAO是基于Microsoft Jet引擎的,所以DAO肯定要在Access數(shù)據(jù)庫(kù)上多作一些文章。例如,調(diào)用CDaoDatabase::Create()函數(shù)可以直接建立一個(gè)MDB文件,代碼如下所示:
m_db.Create("C:\\MYDIR\\MYDB.MDB");
利用AppWizard和ClassWizard,用戶可以方便地開發(fā)出性能優(yōu)良的基于DAO的Access數(shù)據(jù)庫(kù)應(yīng)用程序。