VC++60入門第九章連接數(shù)據(jù)庫_第1頁
VC++60入門第九章連接數(shù)據(jù)庫_第2頁
VC++60入門第九章連接數(shù)據(jù)庫_第3頁
VC++60入門第九章連接數(shù)據(jù)庫_第4頁
VC++60入門第九章連接數(shù)據(jù)庫_第5頁
已閱讀5頁,還剩16頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第九章連接數(shù)據(jù)庫微機(jī)在商業(yè)上的應(yīng)用主要在數(shù)據(jù)處理,要求能夠快速方便地訪問一個大型數(shù)據(jù)庫中的記錄,MFC提供了兩種獨(dú)立地面向用戶的數(shù)據(jù)庫訪問系統(tǒng),一種是ODBC(OpenDataBaseConnectivity,開放數(shù)據(jù)庫連接),另一種是DAO(DataAccessObjects,數(shù)據(jù)訪問對象)。本章你將學(xué)會使用ODBC和DAO連接數(shù)據(jù)庫,并能夠簡單地操作數(shù)據(jù)庫數(shù)據(jù)。9.1MFCODBC連接數(shù)據(jù)庫ODBC是微軟公司支持開放數(shù)據(jù)庫服務(wù)體系的重要組成部分,它定義了一組規(guī)范,提供了一組對數(shù)據(jù)庫訪問的標(biāo)準(zhǔn)API,這些API是建立在標(biāo)準(zhǔn)化版本SQL(StructedQueryLanguage,結(jié)構(gòu)化查詢語言)基礎(chǔ)上的。ODBC位于應(yīng)用程序和具體的DBMS之間,目的是能夠使應(yīng)用程序端不依賴于任何DBMS,與不同數(shù)據(jù)庫的操作由對應(yīng)的DBMS的ODBC驅(qū)動程序完成。9.1.1ODBC的構(gòu)成ODBC的結(jié)構(gòu)如圖9-1所示。ODBC層由三個部件構(gòu)成:ODBC管理器ODBC管理器的主要任務(wù)是管理安裝ODBC驅(qū)動程序,管理數(shù)據(jù)源。應(yīng)用程序要訪問數(shù)據(jù)庫,首先必須在ODBC管理器中創(chuàng)建一個數(shù)據(jù)源。ODBC管理器根據(jù)數(shù)據(jù)源提供的數(shù)據(jù)庫存儲位置,類型及ODBC驅(qū)動程序信息,建立起ODBC與一個特定數(shù)據(jù)庫之間的聯(lián)系,接下來,程序中只需提供數(shù)據(jù)源名,ODBC就能連接相關(guān)的數(shù)據(jù)庫。ODBC管理器位于系統(tǒng)控件面板中。驅(qū)動程序管理器驅(qū)動器管理器位于。。8。32。11,是ODBC中最重要的部件,應(yīng)用程序通過ODBCAPI執(zhí)行數(shù)據(jù)庫操作。其實(shí)ODBCAPI不能直接操作數(shù)據(jù)庫,需要通過驅(qū)動管理器調(diào)用特定的數(shù)據(jù)庫的驅(qū)動程序,驅(qū)動程序在執(zhí)行完相應(yīng)操作后,再將結(jié)果通過驅(qū)動程序管理器返回。驅(qū)動器管理器支持一個應(yīng)用程序同時訪問多個DBMS中的數(shù)據(jù)。3.ODBC驅(qū)動程序ODBC驅(qū)動程序以DLL文件形式出現(xiàn),提供ODBC與數(shù)據(jù)庫之間的接口。9.1.2MFCODBC類進(jìn)行ODBC編程,有三個非常重要的元素:環(huán)境(Enviroment),連接(Connection)和語句(Statement),它們都是通過句柄來訪問的。在MFC的類庫中,CDatabase類封裝了ODBC編程的連接句柄,CRecordset類封裝了對ODBC編程的語句句柄,而環(huán)境句柄被保存在一個全局變量中,可以調(diào)用一個全局函數(shù)AfxGetHENV來獲得當(dāng)前被MFC使用的環(huán)境句柄。此外CRecordView類負(fù)責(zé)記錄集的用戶界面,CFieldExchange負(fù)責(zé)CRedordset類與數(shù)據(jù)源的數(shù)據(jù)交換。使用AppWizard生成應(yīng)用程序框架過程中,只要選擇了相應(yīng)的數(shù)據(jù)庫支持選項(xiàng),你就能夠很方便地獲得一個數(shù)據(jù)庫應(yīng)用程序的框架。CDatabase類CDatabase類的主要功能是建立與ODBC數(shù)據(jù)源的連接,連接句柄放在其數(shù)據(jù)成員m_hdbc中,并提供一個成員函數(shù)GetConnect()用于獲取連接字符串。要建立與數(shù)據(jù)源的連接,首先創(chuàng)建一個CDatabase對象,再調(diào)用CDatabase類的Open()函數(shù)創(chuàng)建連接。Open()函數(shù)的原型定義如下:virtulBOOLOpen(LPCTSTRlpszDSN,BOOLbExclusive=FALSE,BOOLbReadOnly=FALSE,LPCTSTRlpszConnect=”O(jiān)DBC;'',BOOLbUseCursorLib=TRUE);其中:lpszDSN指定數(shù)據(jù)源名,若lpszDSN的值為NULL時,在程序執(zhí)行時會彈出數(shù)據(jù)源對話框,供用戶選擇一個數(shù)據(jù)源。lpszConnect指定一個連接字符串,連接字符串中通常包括數(shù)據(jù)源名、用戶ID、口令等信息,與特定的DBMS相關(guān)。例如:CDatabasedb;db.Open(NULL,FALSE,FALSE,”O(jiān)DBC;DSN=HotelInfO;UID=SYSTEM;PWD=123456”);從斷開與一個數(shù)據(jù)源的連接,可以調(diào)用CDatabase類的成員函數(shù)Close()。CRecordset類CRecordset類對象表示從數(shù)據(jù)源中抽取出來的一組記錄集。CRecordset類封裝了大量操作數(shù)據(jù)庫的函數(shù),支持查詢,存取,更新數(shù)據(jù)庫操作。記錄集主要分為兩種類型:快照(Snapshot)記錄集快照記錄集相當(dāng)于數(shù)據(jù)庫的一張靜態(tài)視圖,一旦從數(shù)據(jù)庫抽取出來,當(dāng)別的用戶更新記錄的操作是不會改變記錄集,只有調(diào)用Requry()函數(shù)重新查詢數(shù)據(jù),才能反映數(shù)據(jù)的變化。自身用戶的添加記錄操作重要調(diào)用Requry()函數(shù)重新查詢數(shù)據(jù),但快照集能反應(yīng)自身用戶的刪除和修改操作。動態(tài)(Dynaset)記錄集動態(tài)(Dynaset)記錄集與快照記錄集恰恰相反,是數(shù)據(jù)庫的動態(tài)視圖。當(dāng)別的用戶更新記錄時,動態(tài)記錄集能即時反映所作的修改。在一些實(shí)時系統(tǒng)中必須采用動態(tài)記錄集,如火車標(biāo)聯(lián)網(wǎng)購票系統(tǒng)。但別的用戶添加記錄,也需要調(diào)用Requry()函數(shù)重新查詢數(shù)據(jù)后才能反映出來。

CRecordset有六個重要的數(shù)據(jù)成員如表9-1所示.。表9-1CRecordset類E勺數(shù)據(jù)成員數(shù)據(jù)成員類型說明m_strFilterCString篩選條件字符串m_strSortCString排序關(guān)鍵字字符串m_pDatabaseCDatabase類指針指向CDatabasec對象的指針m_hstmtHSTMTODBC語句句柄m_nFieldUINT記錄集中字段數(shù)據(jù)成員總數(shù)m_nParamsUINT記錄集中參數(shù)數(shù)據(jù)成員總數(shù)CRecordset的主要成員函數(shù)如表9-2所示:表9-2CRecordset類的成員函數(shù)成員函數(shù)類型Move當(dāng)前記錄指針移動若干個位置MoveFirst當(dāng)前記錄指針移動到記錄集第一條記錄MoveLast當(dāng)前記錄指針移動到記錄集最后一條記錄MoveNext當(dāng)前記錄指針移動到記錄集下一條記錄MovePrev當(dāng)前記錄指針移動到記錄集前一條記錄SetAbsolutePosition當(dāng)前記錄指針移動到記錄集特定一條記錄AddNew添加一條新記錄Delete刪除一條記錄Edit編輯一條記錄Update更新記錄CancelUpdate取消一條記錄的更新操作Requry重新查詢數(shù)據(jù)源GetDefaultConnect獲得默認(rèn)連接字符串GetDefaultSQL獲得默認(rèn)SQL語句DoFieldExchange記錄集中字段數(shù)據(jù)成員與數(shù)據(jù)源中交換數(shù)據(jù)GetRecordCount獲得記錄集記錄個數(shù)IsEOF判斷當(dāng)前記錄指針是否在最后一個記錄之后IsBOF判斷當(dāng)前記錄指針是否在第一個記錄之前CanUpdate判斷記錄集是否允許更新CRecordView類CRecordView類是CFormView的派生類,支持以控件視圖來顯示當(dāng)前記錄,并提供移動記錄的默認(rèn)菜單和工具欄,用戶可以通過記錄視圖方便地瀏覽、修改、刪除和添加記錄。記錄視圖與對話框一樣使用DDX數(shù)據(jù)交換機(jī)制在視圖中的控件的記錄集成員之間交換數(shù)據(jù),只需使用ClassWizard將控件與記錄集的字段數(shù)據(jù)成員一一綁定。CRecordView的主要函數(shù)如表9-3所示:表9-3CRecordView類的主要成員函數(shù)成員函數(shù)類型OnGetRecordset獲得指向記錄集的指針OnMove當(dāng)前記錄指針移動時,OnMove()函數(shù)更新對當(dāng)前記錄

所作的修改,這是將更新記錄保存的方式。IsOnFirstRecordIsOnLastRecord判斷當(dāng)前記錄是否為記錄集的第一條記錄判斷當(dāng)前記錄是否為記錄集的最后一條記錄IsOnFirstRecordIsOnLastRecordCFieldExchange類CFieldExchange類支持記錄字段數(shù)據(jù)的自動交換,實(shí)現(xiàn)記錄集中字段數(shù)據(jù)成員與相應(yīng)的數(shù)據(jù)源中字段之間的數(shù)據(jù)交換,類似于對話框數(shù)據(jù)自動交換機(jī)制。9?2數(shù)據(jù)庫應(yīng)用程序的實(shí)現(xiàn)9.2.1創(chuàng)建并注冊數(shù)據(jù)源在創(chuàng)建數(shù)據(jù)庫應(yīng)用程序之前,先要準(zhǔn)備好數(shù)據(jù)源。下面我們假設(shè)數(shù)據(jù)庫應(yīng)用程序要連接的數(shù)據(jù)庫hotel.mdb存放在C盤根目錄下,該數(shù)據(jù)庫下有一張TblCustomer的表,如圖9-2所示:圖9-2圖9-2數(shù)據(jù)表"tblCustomer”在Windows操作系統(tǒng)的控制面板中,可以找到數(shù)據(jù)源ODBC管理器的圖標(biāo),如圖9-3所示為windowsXPhomeEditon中的ODBC的圖標(biāo),它的位置在控制面板中的管理工具文件夾。由于所要連接的數(shù)據(jù)庫是由MicrosoftACCESS創(chuàng)建,要求ODBC管理器中安裝有MicrosoftACCESS的ODBC驅(qū)動程序。一般,只需安裝了MicrosoftACCESS軟件,相應(yīng)的ODBC驅(qū)動程序就已經(jīng)默認(rèn)安裝了。DataSources(ODBC)Shortcut2.KB圖9-3ODBC圖標(biāo)鼠標(biāo)雙擊ODBC圖標(biāo),彈出“ODBC數(shù)據(jù)源管理器”對話框,如圖9-4所示。

圖9-4ODBC數(shù)據(jù)源管理器在用戶DSN、系統(tǒng)DSN、文件DSN標(biāo)簽頁中都可以創(chuàng)建一個數(shù)據(jù)源,但所創(chuàng)建的數(shù)據(jù)源的應(yīng)用范圍是不同的:用戶DSN:用戶數(shù)據(jù)源只對當(dāng)前用戶可見,而且只能用于當(dāng)前機(jī)器上。系統(tǒng)DSN:系統(tǒng)數(shù)據(jù)源對當(dāng)前機(jī)器上的所有用戶可見。文件DSN:文件數(shù)據(jù)源可以由安裝了相同驅(qū)動程序的用戶共享。可以根據(jù)所創(chuàng)建的數(shù)據(jù)源的不同的應(yīng)用場合選擇在不同的標(biāo)簽頁下創(chuàng)建數(shù)據(jù)源,在本例中選擇系統(tǒng)DSN。在標(biāo)簽頁中的列表中顯示的是在本機(jī)已創(chuàng)建的系統(tǒng)數(shù)據(jù)源的列表。單擊“Add”按鈕,新建一個數(shù)據(jù)源,彈出“創(chuàng)建新數(shù)據(jù)源”對話框。如圖9-5所示,在ODBC驅(qū)動程序列表中選擇“MicrosoftAccessDriver(*.mdb)”。圖9-5選擇ODBC驅(qū)動程序類別單擊“Finish”按鈕,彈出“ODBCMicrosoftAccess安裝”對話框,如圖9-6所示。在數(shù)據(jù)源名文本框中填入:HotelInfo,單擊“選擇”按鈕,彈出“選擇數(shù)據(jù)庫”對話框,如圖9-7所示,選擇數(shù)據(jù)庫文件c:\hotel.mdb,連續(xù)單擊“OK”按鈕回到前一對話框。ODBCMicrosoftAccessSet叩SystemDatabaseAdvanced...SystemDatabaseAdvanced...NoneLDatabase:Options?Options?圖9-6設(shè)置MicrosoftAccess數(shù)據(jù)源SelectDatabaseDirectories:chenhu2DataFolderDELLDocumentsandSeDRIVERS|v|VReadOnlyV~ExclusiveDatabaseDirectories:chenhu2DataFolderDELLDocumentsandSeDRIVERS|v|VReadOnlyV~ExclusiveDatabaseName|Hotel.mdb~Hotel.mdbUstFilesof已: Drives:fennnndOK|.AccessDatabasesr.rm|Wc:Network...圖9-7選擇數(shù)據(jù)庫最后在系統(tǒng)DSN標(biāo)簽中可以看到創(chuàng)建的數(shù)據(jù)源Hotelinfo出現(xiàn)在數(shù)據(jù)源列表中,如圖9-8所示。圖9-8創(chuàng)建好的系統(tǒng)數(shù)據(jù)源9.2.2創(chuàng)建數(shù)據(jù)庫應(yīng)用框架〖例9-1〗使用AppWizard可以方便地得到一個數(shù)據(jù)庫應(yīng)用程序的框架,創(chuàng)建一個MFCEXE應(yīng)用程序Exam9_1,在向?qū)У牡?步中,選擇單選項(xiàng)“Databaseviewwithoutfilesupport”,如圖9-9所示。單擊“DataSource單擊“DataSource”按鈕,彈出“DataOptions”對話框,選擇單選項(xiàng)ODBC,并在下拉框中選擇事先建立好的數(shù)據(jù)源“HotelInfo”,如圖9-10所示。圖9-10選擇ODBC數(shù)據(jù)源圖9-9設(shè)置數(shù)據(jù)庫支持單擊“OK”按鈕,彈出“SelectDatabaseTables”對話框,列表框中列出了HotelInfo數(shù)據(jù)庫中所包含的表和查詢,選擇應(yīng)用程序所操作的表tblCustomer,如圖9-11所示。圖9-11選擇數(shù)據(jù)庫表單擊“OK”按鈕,結(jié)束數(shù)據(jù)源的設(shè)置工作,在圖9-9中“DataSource”按鈕的下方會出現(xiàn)數(shù)據(jù)源的選擇信息。單擊“Finish”按鈕,完成數(shù)據(jù)庫應(yīng)用程序框架的創(chuàng)建,編譯運(yùn)行這個程序,運(yùn)行結(jié)果如圖9-12所示。應(yīng)用程序包含了數(shù)據(jù)庫記錄基本操作菜單和工具按鈕,視圖是一個對話框,可以添加控件。圖9-12數(shù)據(jù)庫應(yīng)用程序框架運(yùn)行效果選擇工作區(qū)的ClassView,展開類樹,進(jìn)一步觀察AppWizard自動添加的與數(shù)據(jù)庫支持有關(guān)的內(nèi)容。增加了一個CExam9_1Set類,該類代表從HotelInfo中選擇的一組記錄集。程序可以選擇一個表作為一個記錄集,本例選擇了表tblCustomer中的記錄構(gòu)建記錄集,也可以選擇一個查詢的結(jié)果集作為一個記錄集。如程序清單9-1所示。CExam9_1Set構(gòu)造函數(shù)用于創(chuàng)建一個記錄集對象,并把一個CDatabase對象的指針作為參數(shù)傳遞給構(gòu)造函數(shù),以便獲得已由CDatabase對象建立起來的與數(shù)據(jù)源的連接。CExam9_1Set類的成員函數(shù)GetDefaultConnect()用于獲得定義了數(shù)據(jù)源類型和數(shù)據(jù)源名的連接字符串。GetDefaulltSQL()函數(shù)中定義了定義SQL語句的字符串,本例的SQL語句定義了查詢一張表的完整記錄。CExam9_1Set類中定義了與數(shù)據(jù)源表的字段相對應(yīng)的數(shù)據(jù)成員,成員函數(shù)DoFieldExchange()完成記錄集上的字段數(shù)據(jù)成員與數(shù)據(jù)源上當(dāng)前記錄對應(yīng)列之間數(shù)據(jù)的自動交換。程序清單9-1:CExam91Set類classCExam9_1Set:publicCRecordset{public:CExam9_1Set(CDatabase*pDatabase=NULL);DECLARE_DYNAMIC(CExam9_1Set)//Field/ParamData//{{AFX_FIELD(CExam9_1Set,CRecordset)longm_CustomerID;CStringm_LastName;CStringm_FirstName;CStringm_HomeCountry;CStringm_HomeState;CStringm_PhoneNumber;CStringm_Comments;//}}AFX_FIELD//Overrides//ClassWizardgeneratedvirtualfunctionoverrides//{{AFX_VIRTUAL(CExam9_1Set)public:virtualCStringGetDefaultConnect();//DefaultconnectionstringvirtualCStringGetDefaultSQL();//defaultSQLforRecordsetvirtualvoidDoFieldExchange(CFieldExchange*pFX);//RFXsupport//}}AFX_VIRTUAL//Implementation#ifdef_DEBUGvirtualvoidAssertValid()const;virtualvoidDump(CDumpContext&dc)const;#endif};CExam9_1Set::CExam9_1Set(CDatabase*pdb):CRecordset(pdb){〃{{AFX_FIELD_INIT(CExam9_1Set)m_CustomerID=0;m_LastName=_T("");m_FirstName=_T("");mHomeCountry=T("");m_HomeState=_T("");m_PhoneNumber=_T("");m_Comments=_T("");m_nFields=7;//}}AFX_FIELD_INITm_nDefaultType=snapshot;}CStringCExam9_1Set::GetDefaultConnect(){return_T("ODBC;DSN=HotelInfo");}CStringCExam9_1Set::GetDefaultSQL(){return_T("[tblCustomer]");}voidCExam9_1Set::DoFieldExchange(CFieldExchange*pFX){//{{AFX_FIELD_MAP(CExam9_1Set)pFX->SetFieldType(CFieldExchange::outputColumn);RFX_Long(pFX,_T("[CustomerID]"),m_CustomerID);RFX_Text(pFX,_T("[LastName]"),m_LastName);RFX_Text(pFX,_T("[FirstName]"),m_FirstName);RFX_Text(pFX,_T("[HomeCountry]"),m_HomeCountry);RFX_Text(pFX,_T("[HomeState]"),m_HomeState);RFX_Text(pFX,_T("[PhoneNumber]"),m_PhoneNumber);RFX_Text(pFX,_T("[Comments]"),m_Comments);//}}AFX_FIELD_MAP}視圖類CExam9_1View是CRecordView的派生類,CRecordView是記錄視圖,支持在控件中顯示數(shù)據(jù)庫記錄。默認(rèn)提供了移動記錄功能的實(shí)現(xiàn)(第一個,上一個,下一個,最后一個)。定義了一個指向記錄集的指針m_pSet。CRecordView類是CFormView類的派生類,CFormView類的視圖對應(yīng)一個對話框資源,所以CRecordView類從基類中繼承的成員函數(shù)中最重要的是DoDataExchange()函數(shù)和UpdateData()函數(shù),DoDataExchange()函數(shù)實(shí)現(xiàn)記錄集的字段與視圖中控件之間的自動數(shù)據(jù)交換,UpdateData()函數(shù)實(shí)現(xiàn)記錄集的字段與視圖中控件之間實(shí)時交換。9.2.3設(shè)計(jì)記錄操作界面〖例9-2〗打開資源管理器的Dialog文件夾,選擇IDD_EXAM9_1_FORM,在對話框中按圖9-13添加

靜態(tài)控件和編輯框控件,設(shè)置ID編輯框的屬性為只讀。圖9-13記錄操作界面并按表9-4所示,修改編輯框控件的ID屬性。表9-4記錄操作界面控件屬性控件ID控件類型標(biāo)題靜態(tài)文本控件IDIDC_CustomerID編輯框控件靜態(tài)文本控件名IDC_LastName編輯框控件靜態(tài)文本控件姓IDC_FirstName編輯框控件靜態(tài)文本控件國家IDC_HomeCountry編輯框控件靜態(tài)文本控件電話IDC_PhoneCall編輯框控件靜態(tài)文本控件備注IDC_Comments編輯框控件接下來,要將編輯框控件與一個記錄集字段數(shù)據(jù)成員綁定,打開ClassWizard,選擇MemberVariables標(biāo)簽頁,為編輯框控件映射記錄集字段數(shù)據(jù)成員,單擊“AddVariable”,彈出“AddMemberVariable”對話框,在下拉框中選擇由m_pSet指針?biāo)赶虻挠涗浖侄螖?shù)據(jù)成員。如圖9-14所示,為控件IDC_Comments選擇綁定的變量為m_pSet->m_Comments。設(shè)置完畢如圖9-15所示。

圖9-14為視圖控件綁定記錄集字段數(shù)據(jù)成員圖9-15所有控件ID與記錄集的綁定單擊“OK”按鈕,完成設(shè)置,重新運(yùn)行程序,運(yùn)行結(jié)果如圖9-16所示。使用移動記錄的四個工具按鈕,前后瀏覽每一條記錄,當(dāng)移動到第一條記錄時,“第一條”和“上一條”按鈕變灰,當(dāng)移動到最后一條記錄時,“最后一條”和“下一條”按鈕變灰。在瀏覽記錄的過程中,你可以修改各個編輯框中的內(nèi)容,緊接著作一次移動記錄操作,所作的修改就能被保存到數(shù)據(jù)庫中。

圖9-16增加了瀏覽功能后的應(yīng)用程序9.2.4更新記錄更新記錄操作包括修改,添加和刪除記錄,CRecordSet類提供了AddNew()、Delete()、Edit()、Update。、CancelUpdate()、Requery()等成員函數(shù)用于更新記錄。AddNew()函數(shù)用于添加一個新的空記錄,所有字段數(shù)據(jù)成員的值都為NULL。Delete()函數(shù)用于刪除當(dāng)前記錄,Edit()函數(shù)用于修改當(dāng)前記錄各字段數(shù)據(jù)成員的值。Update()函數(shù)用于AddNew和Edit操作后的數(shù)據(jù)的最后保存,CancelUpdate()函數(shù)用于取消任何由AddNew和Edit操作產(chǎn)生的待處理的更新。Requery()函數(shù)用于重新執(zhí)行對記錄集的查詢,當(dāng)記錄集類型是快照型時,快照不反映用戶添加的記錄,這時需要調(diào)用該函數(shù)重新查詢更新后的記錄集。下面在Exam9_1中增加添加新記錄和刪除記錄的功能?!祭?-3〗在“record”記錄下添加三個菜單項(xiàng)如下圖圖9-17所示。一個菜單項(xiàng)是分割線,另外兩個菜單項(xiàng)分別是“增加記錄”和“刪除記錄”。菜單ID設(shè)置為ID_RECORD_ADD和ID_RECORD_DELETE。文件E編輯記錄回:查看如幫助:H)F第二個記錄前一個記錄?下一個記錄四)最后一個記錄E增加記錄刪除記錄圖9-17增加菜單項(xiàng)使用ClassWizard在視圖類為菜單項(xiàng)ID_RECORD_ADD和ID_RECORD_DELETE映射COMMAND消息處理函數(shù),得到成員函數(shù)OnRecordAdd()和OnRecordDelete()。添加CExam9_1View的BOOL類數(shù)據(jù)成員m_addflg,用以記錄是否進(jìn)入添加模式,當(dāng)m_addflg的值為true時,進(jìn)入添加模式。在CExam9_1View的構(gòu)造函數(shù)中初始化m_addflg的值為false。為成員函數(shù)OnRecordAdd()添加代碼,增加一條空記錄,并清除ID編輯框的只讀屬性。實(shí)現(xiàn)代碼如程序清單9-2所示。程序清單9-2:AddRecord菜單消息處理函數(shù)voidCExam9_1View::OnRecordAdd(){//TODO:Addyourcommandhandlercodeherem_pSet->AddNew(); 〃進(jìn)入添加模式m_addflg=true; 〃設(shè)置添加模式標(biāo)志CEdit*m_pCtrl=(CEdit*)GetDlgItem(IDC_CustomerID);m_pCtrl->SetReadOnly(false);〃清除ID編輯框的只讀屬性UpdateData(false);〃用新記錄的字段數(shù)據(jù)成員值更新控件顯示J使用ClassWizard添加CExam9_1View類的虛函數(shù)OnMove()函數(shù),并在OnMove()函數(shù)中添加代碼,通過移動記錄將添加的新記錄保存到表中。實(shí)現(xiàn)代碼如程序清單9-3所示程序清單9-3:OnMove()函數(shù)BOOLCExam9_1View::OnMove(UINTnIDMoveCommand){//TODO:Addyourspecializedcodehereand/orcallthebaseclassif(m_addflg)//添加模式處理{m_addflg=false;UpdateData(true);//使用控件值更新記錄集字段數(shù)據(jù)成員if(m_pSet->CanUpdate())〃將記錄集更新保存到表中m_pSet->Update();m_pSet->Requery();//重新查詢記錄集UpdateData(false);//以更新后的記錄集數(shù)據(jù)成員更新控件顯示CEdit*m_pCtrl=(CEdit*)GetDlgItem(IDC_CustomerID);m_pCtrl->SetReadOnly(true);〃設(shè)置ID編輯框?yàn)橹蛔xreturntrue;}elsereturnCRecordView::OnMove(nIDMoveCommand);J為成員函數(shù)OnRecordDelete()添加代碼,刪除當(dāng)前記錄,實(shí)現(xiàn)代碼如程序清單9-4所示。程序清單9-4:DeleteRecord菜單處理函數(shù)voidCExam91View::OnRecordDelete(){//TODO:Addyourcommandhandlercodeherem_pSet->Delete();//刪除當(dāng)前記錄m_pSet->MoveNext();//移到下一記錄if(m_pSet->IsEOF())//刪除記錄為最后一條記錄處理m_pSet->MoveLast();if(m_pSet->IsBOF())//刪空記錄集處理m_pSet->SetFieldNull(NULL);UpdateData(false);//更新控件顯示J9.2.5排序和篩選CRecordView類有兩個重要的數(shù)據(jù)成員m_strFilter和m_strSort,m_strFilter是用于表示篩選記錄的條件字符串,m_strSort是用于表示排序的關(guān)鍵字的字符串。只要對這兩個數(shù)據(jù)成員賦值,只能實(shí)現(xiàn)排序和篩選。〖例9-3〗首先在應(yīng)用程序Exam9_1中建立兩類排序,每一類是按ID號排序,另一類是按HomeCountry排序。在“查看”菜單下添加三個菜單項(xiàng):一條分隔線、“按ID排序”和“按國家排序”,菜單項(xiàng)ID設(shè)置為ID_VIEW_SORT_ID和ID_VIEW_SORT_COUNTRY。使用ClassWizard為兩個菜單項(xiàng)在視圖類中映射COMMAND消息處理函數(shù)得到,添加代碼如程序清單9-5所示,實(shí)現(xiàn)排序。程序清單9-5:實(shí)現(xiàn)排序的函數(shù)voidCExam9_1View::OnViewSortId(){//TODO:Addyourcommandhandlercodeherem_pSet->m_strSort="CustomerID";//定義排序關(guān)鍵字按ID排序m_pSet->Requery();//重新查詢UpdateData(false);〃更新控件顯示}voidCExam9_1View::OnViewSortCountry(){//TODO:Addyourcommandhandlercodeherem_pSet->m_strSort="HomeCountry";m_pSet->Requery();UpdateData(false);}接著添加篩選條件,在一個對話框中輸入一個國別,則只顯示屬于該國別的顧客記錄。步驟如下:⑴創(chuàng)建一個對話框,并添加控件,如圖9-18所示。設(shè)置編輯框的ID為IDC_FILTER.。為該對話對話框添加一個新的對話框類CFilterDlg并使用ClassWizard為編輯框IDC_FILTER在對話框類CFilterDlg中添加一個Ctring類型的成員變量m_Filter。圖9-18篩選對話框(2)在“查看”菜單下添加一個新的菜單項(xiàng)“篩選”,菜單項(xiàng)ID設(shè)為ID_VIEW_FLITER,使用ClassWizard在CExam9_1View類中為菜單項(xiàng)ID_VIEW_FILTER映射菜單處理函數(shù),得到函數(shù)OnViewFilter()。⑶在CExam9_1View類的實(shí)現(xiàn)文件中使用include命令包含"FilterDlg.h”文件,并在函數(shù)OnViewFilter()中添加代碼,調(diào)用篩選對話框,并按對話框返回的字符串設(shè)置數(shù)據(jù)成員m_strFilter的值,實(shí)現(xiàn)篩選。若對話框返回空串,顯示整個記錄集。程序清單9-6:實(shí)現(xiàn)篩選的函數(shù)voidCExam9_1View::OnViewFilter(){//TODO:AddyourcommandhandlercodehereCFilterDlgdlg;CStringstr;if(dlg.DoModal()==IDOK)//調(diào)用篩選對話框,按OK按鈕返回{ if(dlg.m_Filter.IsEmpty())//編輯框?yàn)榭?,顯示整個記錄集str="";elsestr="HomeCountry=,n+dlg.m_Filter+n,";//定義篩選字符串m_pSet->m_strFilter=str;m_pSet->Requery();//重新查詢記錄集UpdateData(false);//更新控件顯示}J9.3MFCDAO連接數(shù)據(jù)庫DAO(DataAccessObjects)即數(shù)據(jù)對象訪問集,是使用MicrosoftJet訪問數(shù)據(jù)庫的一種技術(shù)。它是WindowsAPI的一部分,可以獨(dú)立于DBMS進(jìn)行數(shù)據(jù)庫訪問。DAO與ODBC是兩種完全不同的訪問機(jī)制,ODBC的工作依賴于數(shù)據(jù)庫制造商提供的驅(qū)動程序,應(yīng)用程序使用ODBCAPI訪問數(shù)據(jù)庫時,是由ODBC管理器將應(yīng)用程序的數(shù)據(jù)庫訪問請示傳遞給相應(yīng)的數(shù)據(jù)庫驅(qū)動程序,驅(qū)動程序再用SQL語句完成DBMS的訪問任務(wù)。DAO則使用MicrosoftJet提供的數(shù)據(jù)庫訪問對象集直接訪問DBMS,速度比ODBC要快。MicrodoftJet本身的數(shù)據(jù)庫格式為MDB。如果你采用的是MDB格式的數(shù)據(jù)庫,又希望提高數(shù)據(jù)庫訪問速度時,可以選擇DAO方式。MFC封裝了DAO的絕大多數(shù)API函數(shù),MFC為DAO封閉的類與ODBC類非常相似,同樣,AppWizard和ClassWizard也提供了類似的支持,所以雖然MFCDAO與MFCODBC的工作機(jī)制不一樣,但是開發(fā)DAO數(shù)據(jù)庫應(yīng)用程序的過程與開發(fā)ODBC數(shù)據(jù)庫程序卻驚人地相似。DaoDatabase類CDaoDatabase類對應(yīng)于CDatabase類,支持與數(shù)據(jù)庫的連接,但它不需要在ODBC管理器中注冊DSN,直接與一個數(shù)據(jù)庫相連。DaoRecordset類CDaoRecordset類對應(yīng)CRecordset類,CDaoRecordset類的數(shù)據(jù)成員和成員函數(shù)與CRecordset類的數(shù)據(jù)成員和成員函數(shù)非常相似,支持同樣的記錄集操作。但由于DAO是直接與數(shù)據(jù)庫相連,所以O(shè)DBC中的GetDefaultConnect()函數(shù)在DAO中是GetDefaultDBName。此外,CDaoRecordset類與數(shù)據(jù)源之間的數(shù)據(jù)交換是采用DFX(DaorecordFieldeXchange)機(jī)制,而OBDC采用的是RFX機(jī)制。CDaoRecordView類CDaoRecordView類對應(yīng)CRecordView類,功能幾乎完全相同。CDaoFieldExchange類CDaoFieldExchange類對應(yīng)CFieldExchange類,支持?jǐn)?shù)據(jù)交換。CDaoTableDef類CDaoTableDef類支持對數(shù)據(jù)庫中表結(jié)構(gòu)的操作,成員函數(shù)Open()打開一張表的結(jié)構(gòu),Create()函數(shù)創(chuàng)建一張新表,CreateField()函數(shù)添加字段,Append()函數(shù)將新添加的表保存到數(shù)據(jù)庫中。CDaoQueryDef類CDaoQueryDef類用于定義一個查詢,并保存到數(shù)據(jù)庫中。使用MFCAppWizard生成基于DAO的數(shù)據(jù)庫應(yīng)用程序,與生成基于ODBC的數(shù)據(jù)庫應(yīng)用程序非常相似,只需在選擇數(shù)據(jù)源的時候選擇DAO單選項(xiàng),然后輸入數(shù)據(jù)庫文件的完整路徑和文件名。最后生成的程序框架與基于ODBC的應(yīng)用程序框架非常類似,后面的操作步驟幾乎一樣。讀者可以自已模仿Exam9-1的操作步驟,以DAO方式重寫程序。圖9-19選擇DAO數(shù)據(jù)源

實(shí)驗(yàn)實(shí)驗(yàn)1:(獨(dú)立練習(xí))重新實(shí)現(xiàn)Exam9_1示例程序,要求在AppWizqrd向?qū)У牡诙讲蛔髦付〝?shù)據(jù)源和選擇數(shù)據(jù)庫表的操作,在生成程序框架后,使用ClassWizard創(chuàng)建一個CRecordset的派生類CCustomerset,再按DAO訪問方

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論