版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
數(shù)據(jù)庫訪問技術(shù)
第11章11.1數(shù)據(jù)庫訪問方式11.2ODBC訪問SQLServer技術(shù)
11.3DAO訪問Access數(shù)據(jù)庫
11.4ADO訪問Access數(shù)據(jù)庫主要內(nèi)容11.1數(shù)據(jù)庫訪問方式11.1.2DAO訪問11.1.3ADO訪問11.1.1ODBC訪問11.1.4ADO.NET訪問模式對(duì)話框根底1.ODBC根本概念2.ODBC的工作原理3.ODBC的結(jié)構(gòu)4.MFC的ODBC類簡(jiǎn)介1、對(duì)話框根本概念
開放式數(shù)據(jù)庫互聯(lián)〔OpenDataBaseConnectivity,簡(jiǎn)稱ODBC〕實(shí)際上是一個(gè)數(shù)據(jù)庫訪問庫,可以使應(yīng)用程序直接操縱數(shù)據(jù)庫中的數(shù)據(jù),具有數(shù)據(jù)庫的獨(dú)立性,ODBC是微軟公司W(wǎng)OSA〔WindowsOpenServiceArchitecture〕的組成局部,是微軟公司提出的開放式數(shù)據(jù)庫互聯(lián)的標(biāo)準(zhǔn)接口,用戶可以通過加載連接到數(shù)據(jù)庫的驅(qū)動(dòng)程序來建立與各種數(shù)據(jù)庫的連接,使用ODBC不僅可以訪問Access、SQLServer、OracleSybase、LotusNotes等數(shù)據(jù)庫,而且可以訪問Excel電子表格以及ASCII數(shù)據(jù)文件等非數(shù)據(jù)庫對(duì)象,這正是ODBC的獨(dú)特之處。一個(gè)基于ODBC的應(yīng)用程序?qū)?shù)據(jù)庫的操作不依賴于任何DBMS,并且不直接與DBMS打交道,所有的數(shù)據(jù)庫操作由對(duì)應(yīng)的DBMS的ODBC驅(qū)動(dòng)程序完成,使用ODBC和MFC的ODBC的類,可以訪問任何數(shù)據(jù)源,包括本地或遠(yuǎn)程的。16位和32位的ODBC驅(qū)動(dòng)程序?qū)τ诤艽蠓秶臄?shù)據(jù)源都是有效的,也就是說,不管是FoxPro、Access還是Oracle數(shù)據(jù)庫,均可用ODBCAPI進(jìn)行訪問。由此可見,ODBC的最大優(yōu)點(diǎn)是以統(tǒng)一的方式處理所有的數(shù)據(jù)庫。1、對(duì)話框根本概念ODBC通過使用驅(qū)動(dòng)程序〔Driver〕提供了很好的數(shù)據(jù)庫獨(dú)立性,驅(qū)動(dòng)程序與具體的數(shù)據(jù)庫有關(guān)。這樣,通過ODBC開發(fā)的數(shù)據(jù)庫應(yīng)用程序,如果想更換所使用的數(shù)據(jù)庫,移植到其他的數(shù)據(jù)庫平臺(tái)是非常容易的。例如以前的應(yīng)用程序使用的是Access數(shù)據(jù)庫,現(xiàn)在希望將其移植到SQLServer數(shù)據(jù)庫上,只需將應(yīng)用程序改換一下驅(qū)動(dòng)程序即可,也就是說應(yīng)用程序不再使用Access數(shù)據(jù)庫的ODBC驅(qū)動(dòng)程序,而使用SQLServer數(shù)據(jù)庫的ODBC驅(qū)動(dòng)程序,很容易移植到不同的數(shù)據(jù)庫平臺(tái)上。1、對(duì)話框根本概念2.ODBC的工作原理一個(gè)完整的ODBC由以下幾個(gè)部件組成:①應(yīng)用程序(Application)。②ODBC管理器(Administrator)。該程序位于Windows控制面板(ControlPanel)的32位ODBC內(nèi),其主要任務(wù)是管理安裝的ODBC驅(qū)動(dòng)程序和管理數(shù)據(jù)源。
2.ODBC的工作原理③驅(qū)動(dòng)程序管理器(DriverManager)。驅(qū)動(dòng)程序管理器包含在ODBC32.DLL中,對(duì)用戶是透明的,其任務(wù)是管理ODBC驅(qū)動(dòng)程序,是ODBC中最重要的部件。④ODBCAPI。⑤ODBC驅(qū)動(dòng)程序。是一些DLL,提供了ODBC和數(shù)據(jù)庫之間的接口。⑥數(shù)據(jù)源。數(shù)據(jù)源包含了數(shù)據(jù)庫位置和數(shù)據(jù)庫類型等信息,實(shí)際上是一種數(shù)據(jù)連接的抽象。各部件之間的關(guān)系如圖11-1所示
圖11-1ODBC各部件關(guān)系圖應(yīng)用程序要訪問一個(gè)數(shù)據(jù)庫,首先必須用ODBC管理器注冊(cè)一個(gè)數(shù)據(jù)源,管理器根據(jù)數(shù)據(jù)源提供的數(shù)據(jù)庫位置、數(shù)據(jù)庫類型及ODBC驅(qū)動(dòng)程序等信息,建立起ODBC與具體數(shù)據(jù)庫的聯(lián)系。只要應(yīng)用程序?qū)?shù)據(jù)源名提供給ODBC,ODBC就能建立起與相應(yīng)的數(shù)據(jù)庫連接。在ODBC中,ODBCAPI不能直接訪問數(shù)據(jù)庫,必須通過驅(qū)動(dòng)程序管理器與數(shù)據(jù)庫交換信息。驅(qū)動(dòng)程序管理器包含在ODBC.DLL或ODBC32.DLL中。驅(qū)動(dòng)程序管理器負(fù)責(zé)將應(yīng)用程序?qū)DBCAPI的調(diào)用傳遞給正確的驅(qū)動(dòng)程序,而驅(qū)動(dòng)程序在執(zhí)行相應(yīng)操作后,將結(jié)果通過驅(qū)動(dòng)程序管理器返回給應(yīng)用程序。在訪問ODBC數(shù)據(jù)源時(shí)需要ODBC驅(qū)動(dòng)程序的支持,在32位Windows環(huán)境中,大都安裝了SQLServer、Access、Paradox、dBase、FoxPro、Excel、Oracle和MicrosoftText等驅(qū)動(dòng)程序。ODBC是通過使用驅(qū)動(dòng)程序〔Driver〕提供數(shù)據(jù)庫獨(dú)立性的。驅(qū)動(dòng)程序是ODBC的一個(gè)重要組件,它是支持ODBC函數(shù)調(diào)用的模塊,通常是一個(gè)DLL,并與具體的數(shù)據(jù)庫有關(guān),例如操作Access數(shù)據(jù)庫要使用Access的ODBC驅(qū)動(dòng)程序,操作SQLServer數(shù)據(jù)庫必須使用SQLServer的ODBC驅(qū)動(dòng)程序。應(yīng)用程序是通過調(diào)用驅(qū)動(dòng)程序所支持的函數(shù)來操作數(shù)據(jù)庫的,因此,如果應(yīng)用程序要操作不同類型的數(shù)據(jù)庫,就要?jiǎng)討B(tài)連接到不同的驅(qū)動(dòng)程序上。許多應(yīng)用程序開發(fā)軟件都提供ODBC接口,VisualC++也不例外,ODBC接口以SQL作為標(biāo)準(zhǔn)的查詢語言來存取連接到的數(shù)據(jù)源,它允許單個(gè)應(yīng)用同時(shí)訪問不同的數(shù)據(jù)庫管理系統(tǒng)〔DBMS〕,這使應(yīng)用程序開發(fā)人員不必關(guān)心所操作的數(shù)據(jù)庫管理系統(tǒng),而能完成應(yīng)用開發(fā)。VisualC++從2.0就開始包含ODBC庫和頭文件,并在MFC類庫中包含了基于ODBC的擴(kuò)展數(shù)據(jù)庫類,它封裝了使用ODBC的細(xì)節(jié),節(jié)省了開發(fā)人員大量工作,使ODBC應(yīng)用程序的開發(fā)變得非常容易。3.ODBC的結(jié)構(gòu)ODBC調(diào)用主要由四個(gè)層次組成,如圖11-2所示。
圖11-2ODBC四層結(jié)構(gòu)〔1〕第一層:ODBC應(yīng)用軟件〔如VisualC++〕,它通過ODBC函數(shù)向數(shù)據(jù)庫發(fā)送SQL語句并處理SQL返回結(jié)果。3.ODBC的結(jié)構(gòu)〔2〕第二層:ODBC驅(qū)動(dòng)管理程序,它負(fù)責(zé)管理和裝載驅(qū)動(dòng)程序,其作用是:①用ODBC.INI文件映射數(shù)據(jù)源到特定驅(qū)動(dòng)程序。②處理ODBC的初始化調(diào)用。③為每個(gè)驅(qū)動(dòng)程序提供ODBC函數(shù)入口。④提供ODBC調(diào)用參數(shù)和順序。3.ODBC的結(jié)構(gòu)〔3〕第三層:ODBC驅(qū)動(dòng)程序,處理ODBC函數(shù)調(diào)用,提交SQL請(qǐng)求給特定的數(shù)據(jù)源并返回結(jié)果給應(yīng)用程序,如果必要,它還修改SQL請(qǐng)求,使得SQL請(qǐng)求的語法與特定數(shù)據(jù)庫的語法一致?!?〕第四層:數(shù)據(jù)源,數(shù)據(jù)源是指要存取的數(shù)據(jù)及其相關(guān)的操作系統(tǒng)、數(shù)據(jù)庫管理系統(tǒng)和網(wǎng)絡(luò)系統(tǒng)。3.ODBC的結(jié)構(gòu)4.MFC的ODBC類簡(jiǎn)介
MFC的ODBC類對(duì)較為復(fù)雜的ODBCAPI進(jìn)行了封裝,提供了簡(jiǎn)化的調(diào)用接口,從而大大方便了數(shù)據(jù)庫應(yīng)用程序開發(fā)。程序員不必了解ODBCAPI和SQL的具體細(xì)節(jié),利用ODBC類即可完成對(duì)數(shù)據(jù)庫的大局部操作。MFC的ODBC類主要包括:CDatabase類:主要功能是建立與數(shù)據(jù)源的連接。CRecordset類:該類代表從數(shù)據(jù)源選擇的一組記錄〔記錄集〕,程序可以選擇數(shù)據(jù)源中的某個(gè)表作為一個(gè)記錄集,也可以通過對(duì)表的查詢得到記錄集,還可以合并同一數(shù)據(jù)源中多個(gè)表的列到一個(gè)記錄集。通過該類可對(duì)記錄集中的記錄進(jìn)行滾動(dòng)、修改、增加和刪除等操作。CRecordView類:提供了一個(gè)表單視圖,它與某個(gè)記錄集直接相連,利用對(duì)話框數(shù)據(jù)交換機(jī)制(DDX)在記錄集與表單視圖的控件之間交換數(shù)據(jù),該類支持對(duì)記錄的瀏覽和更新,在銷毀時(shí),會(huì)自動(dòng)關(guān)閉與之相聯(lián)系的記錄集。CFieldExchange類:支持記錄字段數(shù)據(jù)交換〔DFX〕,即記錄集字段數(shù)據(jù)成員與相應(yīng)數(shù)據(jù)庫的表字段之間的數(shù)據(jù)交換,該類功能與CDataExchange類的對(duì)話框數(shù)據(jù)交換功能類似。CDBException類:代表ODBC類產(chǎn)生的異常。MFC的ODBC類主要包括:
概括起來:CDatabase針對(duì)某個(gè)數(shù)據(jù)庫,負(fù)責(zé)
連接數(shù)據(jù)源;CRecordset針對(duì)數(shù)據(jù)源中的記錄集,
負(fù)責(zé)對(duì)記錄的操作;CRecordView負(fù)責(zé)界面;CFieldExchange負(fù)責(zé)CRecordset
與數(shù)據(jù)源的數(shù)據(jù)交換。MFC的ODBC類主要包括:
1.什么是DAO2.DAO與ODBC的比較3.DAO的特色11.1.2DAO訪問什么是DAODAO〔DatabaseAccessObject〕使用MicrosoftJet數(shù)據(jù)庫引擎來訪問數(shù)據(jù)庫,提供了一種新的數(shù)據(jù)庫編程方式,力求使數(shù)據(jù)庫編程更為簡(jiǎn)單方便。MicrosoftJet為Access和VisualBasic提供了數(shù)據(jù)引擎。因此,如果要直接訪問由Microsoft產(chǎn)品創(chuàng)立的數(shù)據(jù)庫,如Access數(shù)據(jù)庫,那么DAO是最適宜的,它會(huì)使數(shù)據(jù)庫的訪問速度更快,更易于使用。
與ODBC一樣,DAO提供了一組API供編程使用,MFC也提供了一組DAO類,封裝了底層的API,大大簡(jiǎn)化了程序的開發(fā),利用MFC的DAO類,用戶可以編寫?yīng)毩⒂贒BMS的應(yīng)用程序。DAO是從VisualC++4.0開始引入,一般來說,DAO類提供了比ODBC類更廣泛的支持,一方面,只要有ODBC驅(qū)動(dòng)程序,使用MicrosoftJet的DAO就可以訪問ODBC數(shù)據(jù)源。另一方面,由于DAO是基于MicrosoftJet引擎的,因而在訪問Access數(shù)據(jù)庫〔*.MDB文件〕時(shí)具有更好的性能。同時(shí)DAO也可直接用于其他一些文件訪問,但性能不佳,包括以下幾種:①文本文件:按某種方式格式化的文本文件,如標(biāo)準(zhǔn)分界文件,它使用逗號(hào)分界符隔離字段,回車分界符別離每條記錄,用雙引號(hào)限定文本。②MicrosoftExcel表格文件:DAO可訪問用MicrosoftExcel創(chuàng)立的電子表格文件。
③Lotus表格文件:DA0可訪問WKS、WK1、WK3以及WK4文件類型的Lotus表格文件。④ISAM數(shù)據(jù)庫ISAM〔索引順序訪問方式〕數(shù)據(jù)庫主要包括dBASE、FoxBase、FoxPro等,DAO可訪問它們的數(shù)據(jù)庫文件。2.DAO與ODBC的比較
如果利用VisualC++開發(fā)數(shù)據(jù)庫應(yīng)用,究竟選擇ODBC方式還是DAO方式經(jīng)常是困擾開發(fā)者的一個(gè)問題。在此,我們對(duì)ODBC和DAO進(jìn)行一些比較,以幫助開發(fā)者在實(shí)際的數(shù)據(jù)庫開發(fā)中進(jìn)行決策,盡量做到既保證應(yīng)用程序的性能,又使編程工作相對(duì)輕松。DAO與ODBC的比較①二者都支持對(duì)各種ODBC數(shù)據(jù)源的訪問。雖然二者使用的數(shù)據(jù)引擎不同,但都可以滿足用戶編寫?yīng)毩⒂贒BMS應(yīng)用程序的要求。②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ù)都是相同的。③應(yīng)用程序向?qū)Ш皖愊驅(qū)?duì)使用DAO和ODBC對(duì)象的應(yīng)用程序提供了類似的支持。3.DAO的特色
DAO可以通過ODBC驅(qū)動(dòng)程序訪問ODBC
數(shù)據(jù)源。但DAO是基于MicrosoftJet引擎的,通過該引擎,DAO可以直接訪問Access、FoxPro、dBASE、Paradox、Excel和LotusWK等數(shù)據(jù).CDaoDatabase
類可以直接與這些數(shù)據(jù)庫進(jìn)行連接,而不必在ODBC管理器中注冊(cè)DSN。
支持DDL是DAO對(duì)數(shù)據(jù)庫編程良好支持的一個(gè)重要表達(dá)。DDL(DataDefinitionLanguage)在SQL術(shù)語中叫做“數(shù)據(jù)定義語言〞,它用來完成生成、修改和刪除數(shù)據(jù)庫結(jié)構(gòu)的操作。ODBC類只支持DML〔DataManipulationLanguage,數(shù)據(jù)操作語言〕,不支持DDL,所以用ODBC類只能完成數(shù)據(jù)的操作,不涉及數(shù)據(jù)庫的結(jié)構(gòu)。要執(zhí)行DDL操作,只有通過ODBCAPI。而DAO類同時(shí)提供了對(duì)DML和DDL的支持,這意味著程序可以使用DAO類方便的創(chuàng)立數(shù)據(jù)庫以及修改數(shù)據(jù)庫的結(jié)構(gòu)。
DAO的另一個(gè)重要特色在于它對(duì)Access數(shù)據(jù)庫提供了強(qiáng)大的支持。由于DAO是基于MicrosoftJet引擎的,所以DAO對(duì)Access數(shù)據(jù)庫的支持更多一些,例如,調(diào)用CDaoDatabase::Create可以創(chuàng)立一個(gè)MDB文件。利用應(yīng)用程序向?qū)Ш皖愊驅(qū)В脩艨梢苑奖愕亻_發(fā)出性能優(yōu)良的基于DAO的Access數(shù)據(jù)庫應(yīng)用程序。11.1.3ADO訪問ADO是Windows環(huán)境比較流行的客戶端數(shù)據(jù)庫訪問技術(shù),建立在OLEDB底層技術(shù)之上的高級(jí)編程接口。一方面具有強(qiáng)大的數(shù)據(jù)處理能力,可以處理各種不同類型的數(shù)據(jù)源、分布式數(shù)據(jù)等,另一方面具有極其簡(jiǎn)單、易用的編程接口,得到了越來越多的應(yīng)用。ADO數(shù)據(jù)庫訪問技術(shù)實(shí)際上就是一組Automation對(duì)象組件,因此ADO的使用和其它任何Automation對(duì)象的使用沒有區(qū)別。ADO訪問技術(shù)中最主要的三個(gè)對(duì)象分別是:Connection、Command和Recordset,分別代表“連接對(duì)象〞、“命令對(duì)象〞和“記錄集對(duì)象〞。本章第4節(jié)將進(jìn)一步討論在VS2023開發(fā)環(huán)境中如何實(shí)現(xiàn)ADO的數(shù)據(jù)庫訪問。11.1.4ADO.NET訪問除了ODBC、DAO和ADO訪問方式外,還有時(shí)下流行的基于.NET平臺(tái)的ADO.NET數(shù)據(jù)庫訪問技術(shù),它是.NET環(huán)境下連接數(shù)據(jù)庫的重要技術(shù),但采用該技術(shù)開發(fā)的應(yīng)用程序必須要.NET運(yùn)行環(huán)境支持。和ADO訪問技術(shù)類似,ADO.NET是.NET框架下一組操作數(shù)據(jù)庫的對(duì)象組件〔.NET組件〕,其工作流程如圖11-3所示。通過這些對(duì)象可以完成數(shù)據(jù)庫連接、數(shù)據(jù)查看、插入、更新和刪除以及數(shù)據(jù)庫的關(guān)閉等根本操作。ADO.NET數(shù)據(jù)庫訪問根本流程圖11-3ADO.NET數(shù)據(jù)庫訪問根本流程ADO.NET主要有以下六個(gè)對(duì)象:〔1〕Connection:使用一個(gè)連接字符串建立與特定數(shù)據(jù)源的連接;〔2〕Command:針對(duì)數(shù)據(jù)源執(zhí)行SQL命令;〔3〕DataReader:從數(shù)據(jù)源獲取只讀的數(shù)據(jù);〔4〕DataAdapter:在DataSet和數(shù)據(jù)源之間傳遞數(shù)據(jù);〔5〕DataSet:包含一個(gè)或多個(gè)DataTable對(duì)象組成的集合,是一個(gè)容器;〔6〕DataView:實(shí)現(xiàn)對(duì)DataSet中數(shù)據(jù)進(jìn)行排序、過濾和查找等操作。以上簡(jiǎn)要介紹了Windows平臺(tái)下數(shù)據(jù)庫訪問的主要技術(shù)及其特點(diǎn),開發(fā)人員可根據(jù)具體情況選擇適宜的數(shù)據(jù)庫訪問技術(shù),使開發(fā)效率和系統(tǒng)性能到達(dá)最正確。11.1數(shù)據(jù)庫訪問方式11.2ODBC訪問SQLServer技術(shù)
11.3DAO訪問Access數(shù)據(jù)庫
11.4ADO訪問Access數(shù)據(jù)庫
主要內(nèi)容11.2ODBC訪問SQLServer技術(shù)11.2.1記錄集與記錄視11.2.2數(shù)據(jù)庫操作11.2.3記錄集的操作11.2.4ODBC應(yīng)用舉例11.2.5多表操作應(yīng)用舉例1.記錄集CRecordset類代表一個(gè)記錄集。在多任務(wù)操作系統(tǒng)或網(wǎng)絡(luò)環(huán)境中,多個(gè)用戶可以共享同一個(gè)數(shù)據(jù)源。共享數(shù)據(jù)的主要問題是如何協(xié)調(diào)各個(gè)用戶對(duì)數(shù)據(jù)源的修改。對(duì)基于MFC的ODBC應(yīng)用程序來說,主要取決于應(yīng)用程序所采用的記錄集的種類。根據(jù)其它應(yīng)用改變數(shù)據(jù)后處理方式的差異。記錄集可分為快照〔Snapshot〕和動(dòng)態(tài)集〔Dynaset〕兩種?!?〕快照記錄集提供了對(duì)數(shù)據(jù)的靜態(tài)視。如同對(duì)數(shù)據(jù)源的某些記錄照了一張照片,當(dāng)其它用戶改變記錄時(shí)〔如修改、添加和刪除〕,快照中的記錄不受影響,除非通過CRecordset::Requery重新查詢。對(duì)于產(chǎn)生報(bào)表、執(zhí)行計(jì)算不需要中途變動(dòng)的任務(wù),快照是最理想的方式??煺盏倪@種靜態(tài)特性是相對(duì)于其它用戶來說的,用戶自身對(duì)記錄的修改和刪除,快照能夠及時(shí)反映,但對(duì)新增記錄,只有調(diào)用Requery后才能正確反映到快照中?!?〕動(dòng)態(tài)集提供了數(shù)據(jù)的動(dòng)態(tài)視。當(dāng)其它用戶修改或刪除記錄時(shí),動(dòng)態(tài)集會(huì)自動(dòng)更新。當(dāng)用戶移動(dòng)到修改正的記錄時(shí),會(huì)看到其他用戶所作的修改;當(dāng)記錄被其他用戶刪除時(shí),動(dòng)態(tài)集會(huì)跳過記錄集中刪除的局部,這樣也看到其他用戶的刪除;但對(duì)其他用戶添加的記錄,只有調(diào)用Requery后,新增加的記錄才會(huì)在動(dòng)態(tài)集中反映出來。應(yīng)用程序自身對(duì)記錄的修改、添加和刪除會(huì)自動(dòng)反映在動(dòng)態(tài)集中。當(dāng)數(shù)據(jù)自身具有動(dòng)態(tài)特性時(shí),使用動(dòng)態(tài)集是最理想的。光標(biāo)庫〔CursorLibrary〕是處于ODBC驅(qū)動(dòng)程序管理器和驅(qū)動(dòng)程序之間的動(dòng)態(tài)鏈接庫〔ODBCCR32.DLL〕,主要功能是為快照和底層驅(qū)動(dòng)程序提供雙向滾動(dòng)能力,負(fù)責(zé)管理快照記錄的緩沖區(qū)??煺沼涗浘彌_區(qū)只能反映應(yīng)用程序自身對(duì)記錄所做的修改和刪除,不能反映其他用戶對(duì)記錄的更改。快照是一種靜態(tài)光標(biāo)〔StaticCursor〕,其特點(diǎn)是只有滾動(dòng)到某個(gè)記錄才能取得該記錄的數(shù)據(jù)。如果要保證所有的記錄都被快照,必須從記錄集的開始滾動(dòng)到末尾,然后再滾動(dòng)到某一記錄,顯然從開始滾動(dòng)到末尾增加了系統(tǒng)的額外開銷,降低了性能。與快照不同,動(dòng)態(tài)集不是用光標(biāo)庫維持緩沖區(qū)來存取記錄,而是一種鍵集驅(qū)動(dòng)光標(biāo)〔Keyset-DrivenCursor〕,當(dāng)翻開動(dòng)態(tài)集時(shí),驅(qū)動(dòng)程序保存記錄集中每個(gè)記錄的鍵,只要光標(biāo)在動(dòng)態(tài)集中滾動(dòng),驅(qū)動(dòng)程序就會(huì)通過鍵來從數(shù)據(jù)源中檢取當(dāng)前記錄,從而保證選取的記錄與數(shù)據(jù)源同步。快照和動(dòng)態(tài)集具有一個(gè)共同特點(diǎn),在建立記錄集后,記錄集中的成員就已經(jīng)確定,這也就是快照和動(dòng)態(tài)集都不能反映其他用戶添加記錄的原因所在CRecordView〔記錄視圖〕是CFormView的派生類,它提供了一個(gè)表單視圖來顯示當(dāng)前記錄,用戶可以通過表單視圖顯示當(dāng)前記錄,通過記錄視圖,可以修改、添加和刪除數(shù)據(jù)。用戶一般需要?jiǎng)?chuàng)立一個(gè)CRecordView的派生類,并在對(duì)應(yīng)的對(duì)話框模板中添加控件。
2.記錄視圖
3.記錄集與記錄視圖的關(guān)系記錄視圖是一個(gè)連接到記錄集的窗體視圖類,通過使用DDX數(shù)據(jù)交換機(jī)制在表單控件和記錄集之間交換數(shù)據(jù)。當(dāng)用戶在控件中輸入數(shù)據(jù)時(shí),記錄視圖的DDX〔對(duì)話框數(shù)據(jù)交換〕把數(shù)據(jù)移到記錄集的數(shù)據(jù)成員中,這些數(shù)據(jù)成員又被記錄集的RFX〔記錄字段交換〕綁定到數(shù)據(jù)庫的字段上。在應(yīng)用程序向?qū)蓱?yīng)用程序的過程中,如果指定了數(shù)據(jù)庫視圖應(yīng)用程序,應(yīng)用程序向?qū)a(chǎn)生一個(gè)CRecordView派生類和一個(gè)CRecordset的派生類,兩者在運(yùn)行時(shí)被連接起來,而且生成一個(gè)空的對(duì)話框模板。這樣,用戶只需要在對(duì)話框模板上添加控件,并把這些控件與記錄集數(shù)據(jù)成員做匹配,而不需要額外編程,簡(jiǎn)化了數(shù)據(jù)庫應(yīng)用開發(fā)過程。11.2.2數(shù)據(jù)庫操作建立與數(shù)據(jù)源的連接,首先應(yīng)構(gòu)造一個(gè)CDatabase對(duì)象,然后調(diào)用CDatabase的Open成員函數(shù),建立數(shù)據(jù)庫連接,Open函數(shù)原型如下:virtualBOOLOpen(LPCTSTRlpszDSN,BOOLbExclusive=FALSE,BOOLbReadOnly=FALSE,LPCTSTRlpszConnect=“ODBC;〞,BOOLbUseCursorLib=TRUE);throw(CDBException,CMemoryException);參數(shù)lpszDSN指定了數(shù)據(jù)源名〔構(gòu)造數(shù)據(jù)源的方法將在后面介紹〕,在lpszConnect參數(shù)中也可包括數(shù)據(jù)源名,此時(shí)lpszDSN必須為NULL,假設(shè)在函數(shù)中未提供數(shù)據(jù)源名且使lpszDSN為NULL,那么會(huì)顯示一個(gè)數(shù)據(jù)源對(duì)話框,用戶可以在該對(duì)話框中選擇一個(gè)數(shù)據(jù)源。參數(shù)bExclusive說明是否獨(dú)占數(shù)據(jù)源,該參數(shù)一般設(shè)是FALSE,說明數(shù)據(jù)源是共享的。參數(shù)bReadOnly假設(shè)為TRUE那么對(duì)數(shù)據(jù)源的連接是只讀的。參數(shù)lpszConnect指定了一個(gè)連接字符串,連接字符串中可以包括數(shù)據(jù)源名、用戶帳號(hào)〔ID〕和密碼等信息,字符串中的“ODBC〞表示要連接到一個(gè)ODBC數(shù)據(jù)源上。參數(shù)bUseCursorLib假設(shè)為TRUE,那么會(huì)裝載光標(biāo)庫,否那么不裝載,快照需要光標(biāo)庫,動(dòng)態(tài)集不需要光標(biāo)庫。假設(shè)連接成功,函數(shù)返回TRUE,否那么返回FALSE。11.2.3記錄集的操作建立記錄集,首先構(gòu)造一個(gè)CRecordset派生類對(duì)象,然后調(diào)用Open成員函數(shù)查詢數(shù)據(jù)源中的記錄并建立記錄集,其函數(shù)聲明如下:CRecordset(CDatabase*pDatabase=NULL);參數(shù)pDatabase指向一個(gè)CDatabase對(duì)象,用來獲取數(shù)據(jù)源。如果pDatabase為NULL,那么會(huì)在Open函數(shù)中自動(dòng)構(gòu)建一個(gè)CDatabase對(duì)象。如果CDatabase對(duì)象還未與數(shù)據(jù)源連接,那么在Open函數(shù)中會(huì)建立連接,連接字符串由成員函數(shù)GetDefaultConnect提供。Open成員函數(shù)使用指定SQL語句查詢數(shù)據(jù)源中的記錄并按指定的類型和選項(xiàng)建立記錄集,其函數(shù)聲明如下:virtualBOOLOpen(UINTnOpenType=AFX_DB_USE_DEFAULT_TYPE,LPCTSTRlpszSQL=NULL,DWORDdwOptions=none);throw(CDBException,CMemoryException);參數(shù)nOpenType說明了記錄集的類型,如表11-1所示,如果要求的類型驅(qū)動(dòng)程序不支持,那么該函數(shù)將產(chǎn)生一個(gè)異常。參數(shù)lpszSQL是一個(gè)SQL的SELECT語句,或是一個(gè)表名,用于查詢,如果該參數(shù)為NULL,那么函數(shù)會(huì)調(diào)用GetDefaultSQL獲取缺省的SQL語句。參數(shù)dwOptions可以是一些選項(xiàng)組合,常用選項(xiàng)在表11-2中列出。假設(shè)創(chuàng)立成功那么返回TRUE,否那么返回FALSE。通過合理地安排SQL語句和表名,Open函數(shù)可以非常靈活地查詢數(shù)據(jù)源中的記錄,可以合并多個(gè)表的字段,也可以只選擇記錄中的某些字段,還可以對(duì)記錄進(jìn)行過濾和排序。如果在調(diào)用Open時(shí)只提供了表名,框架規(guī)定,如果只提供了表名,那么選擇列的信息從DoFieldExchange的RFX語句里提取,防止SELECT語句缺少選擇列參數(shù)rfx-field-list。建立記錄集后,用戶可以隨時(shí)調(diào)用Requery成員函數(shù)來重新查詢和建立記錄集,該函數(shù)有兩個(gè)目的:①使記錄集能反映用戶對(duì)數(shù)據(jù)源的修改②按照新的過濾或排序方法查詢記錄,并重新建立記錄集在調(diào)用Requery之前,需要調(diào)用CanRestart函數(shù)判斷記錄集是否支持Requery操作。再者,Requery只能在成功調(diào)用Open后調(diào)用,因此在Requery之前還需要調(diào)用IsOpen判斷記錄集是否已建立,下面給出Requery函數(shù)聲明:virtualBOOLRequery();throw(CDBException,CMemoryException);返回TRUE說明記錄集建立成功,否那么返回FALSE,假設(shè)函數(shù)內(nèi)部出錯(cuò)那么產(chǎn)生異常。
CRecordset類有兩個(gè)公共數(shù)據(jù)成員m_strFilter和m_strSort用來設(shè)置對(duì)記錄的過濾和排序。在調(diào)用Open或Requery之前,如果這兩個(gè)數(shù)據(jù)成員指定了過濾或排序條件,那么Open和Requery將按這兩個(gè)數(shù)據(jù)成員指定的過濾和排序來檢索數(shù)據(jù)源。〔1〕成員m_strFilter用于指定過濾器,m_strFilter實(shí)際上包含了SQL的WHERE子句的內(nèi)容,但它不含WHERE關(guān)鍵字?!?〕成員m_strSort用于指定排序,m_strSort實(shí)際上包含了ORDERBY子句的內(nèi)容,但它不含ORDERBY關(guān)鍵字。事實(shí)上,Open函數(shù)在構(gòu)造SELECT語句時(shí),會(huì)把m_strFilter和m_strSort的內(nèi)容放入SELECT語句的WHERE和ORDERBY子句中。如果在Open的lpszSQL參數(shù)中已包括了WHERE和ORDERBY子句,那么m_strFilter和m_strSort必須為空。調(diào)用無參數(shù)成員函數(shù)Close關(guān)閉記錄集,在調(diào)用Close函數(shù)后,程序可以再次調(diào)用Open建立新的記錄集。CRecordset的析構(gòu)函數(shù)會(huì)調(diào)用Close函數(shù),所以當(dāng)刪除CRecordset對(duì)象時(shí)記錄集也隨之關(guān)閉。2.滾動(dòng)記錄CRecordset提供了幾個(gè)成員函數(shù)用來在記錄集中滾動(dòng),當(dāng)用這些函數(shù)滾動(dòng)到一個(gè)新記錄時(shí),框架會(huì)自動(dòng)把新記錄的內(nèi)容拷貝到數(shù)據(jù)成員中。
voidMoveNext();
//前進(jìn)一個(gè)記錄
voidMovePrev();
//后退一個(gè)記錄
voidMoveFirst();
//滾動(dòng)到記錄集中的第一個(gè)記錄voidMoveLast();
//滾動(dòng)到記錄集中的最后一個(gè)記錄voidSetAbsolutePosition(longnRows);
SetAbsolutePosition函數(shù)用于滾動(dòng)到由參數(shù)nRows指定的絕對(duì)位置,如果nRows為-1時(shí),函數(shù)就滾動(dòng)到記錄集的末尾。注意,該函數(shù)不會(huì)跳過被刪除的記錄
3.修改、添加和刪除記錄(1)修改當(dāng)前記錄①調(diào)用Edit函數(shù)進(jìn)入編輯模式,該函數(shù)會(huì)把當(dāng)前數(shù)據(jù)成員的內(nèi)容保存在一個(gè)緩沖區(qū)中,一方面可以和數(shù)據(jù)成員作比較以判斷哪些字段被改變了,另一方面在必要的時(shí)候可以恢復(fù)數(shù)據(jù)成員原來的值。如果再次調(diào)用Edit,記錄集將從緩沖區(qū)中恢復(fù)數(shù)據(jù)成員,而且程序仍處于編輯模式。調(diào)用Move(AFX_MOVE_REFRESH)或Move(0)可退出編輯模式,同時(shí)該函數(shù)會(huì)從緩沖區(qū)中恢復(fù)數(shù)據(jù)成員。提示:不要在一個(gè)空的記錄集中調(diào)用Edit,否那么會(huì)產(chǎn)生異常。②設(shè)置數(shù)據(jù)成員的新值。③調(diào)用Update把變化后的記錄寫入數(shù)據(jù)源并結(jié)束編輯模式。(2)添加新記錄①調(diào)用AddNew函數(shù)進(jìn)入添加模式,該函數(shù)把所有的數(shù)據(jù)成員都設(shè)置成NULL〔在數(shù)據(jù)庫術(shù)語中,NULL是指沒有值,這和C++中的NULL不同)。與Edit一樣,AddNew會(huì)把當(dāng)前數(shù)據(jù)成員的內(nèi)容保存在一個(gè)緩沖區(qū)中,在必要的時(shí)候,程序可以再次調(diào)用AddNew取消添加操作并恢復(fù)數(shù)據(jù)成員原來的值,調(diào)用后,程序仍處于添加模式。調(diào)用Move(AFX_MOVE_REFRESH)可退出添加模式,同時(shí)該函數(shù)會(huì)從緩沖區(qū)中恢復(fù)數(shù)據(jù)成員。②設(shè)置數(shù)據(jù)成員。③調(diào)用Update把數(shù)據(jù)成員中的內(nèi)容作為新記錄寫入數(shù)據(jù)源,結(jié)束添加過程。④如果記錄集是快照,那么在添加一個(gè)新記錄后,還需要調(diào)用Requery重新查詢,因?yàn)榭煺諢o法反映添加操作。(3)刪除當(dāng)前記錄①調(diào)用Delete函數(shù),該函數(shù)同時(shí)給記錄集和數(shù)據(jù)源中當(dāng)前記錄加上刪除標(biāo)記。提示:不要在一個(gè)空記錄集中調(diào)用Delete,否那么會(huì)產(chǎn)生一個(gè)異常。②滾動(dòng)到另一個(gè)記錄上以跳過刪除記錄。在對(duì)記錄集進(jìn)行更改以前,程序需要調(diào)用以下函數(shù)判斷記錄集是否可以更改,如果在不能更改的記錄集中進(jìn)行修改、添加或刪除,將導(dǎo)致異常的產(chǎn)生。BOOLCanUpdate()const; //返回TRUE說明記錄可修改、添加和刪除BOOLCanAppend()const; //返回TRUE說明可以添加記錄。11.2.4ODBC應(yīng)用舉例1.應(yīng)用實(shí)例概述這個(gè)實(shí)例是要完成一個(gè)學(xué)生成績(jī)管理系統(tǒng)的開發(fā),數(shù)據(jù)庫采用SQLServer2005。首先需要在SQLServer上創(chuàng)立一個(gè)名為stu_score的數(shù)據(jù)庫,并創(chuàng)立一個(gè)學(xué)生信息數(shù)據(jù)表〔student〕,存放每個(gè)學(xué)生的信息,包括學(xué)生的學(xué)號(hào)、姓名、系別、專業(yè)、班級(jí)。此實(shí)例向讀者演示了應(yīng)用程序的創(chuàng)立、數(shù)據(jù)的遍歷和查找以及添加、修改和刪除數(shù)據(jù)等功能?!?〕利用VisualC++的應(yīng)用程序向?qū)?chuàng)立ODBC應(yīng)用,生成與學(xué)生信息表student相對(duì)應(yīng)的記錄集類和視圖類,存取并顯示student表中的記錄?!?〕遍歷學(xué)生信息表,將學(xué)生信息添加到學(xué)生信息視圖中,能夠按學(xué)號(hào)查找對(duì)應(yīng)的學(xué)生?!?〕實(shí)現(xiàn)對(duì)學(xué)生信息表的添加、修改、刪除等數(shù)據(jù)操作。
1.應(yīng)用實(shí)例概述
2.建立SQLServer數(shù)據(jù)庫3.建立數(shù)據(jù)源4.建立應(yīng)用程序
〔1〕利用“應(yīng)用程序向?qū)Ж暽蓱?yīng)用程序框架〔2〕創(chuàng)立視圖①編譯連接,如果出現(xiàn)“#error:平安問題:連接字符串可能包含密碼?〞錯(cuò)誤提示,請(qǐng)翻開“類視圖〞,點(diǎn)擊“CS11_1Set〞類節(jié)點(diǎn),定位到GetDefaultConnect函數(shù),如果不擔(dān)憂程序中包含明文密碼的平安性隱患,請(qǐng)將編譯所產(chǎn)生的錯(cuò)誤信息刪除,重新編譯;如果希望用戶每次都輸入密碼,請(qǐng)將連接字符串中的密碼〔“pwd=odbc;〞〕刪除,然后編譯運(yùn)行,這時(shí)在程序啟動(dòng)時(shí),會(huì)彈出一個(gè)如圖11-26所示的對(duì)話框,要求用戶輸入連接到數(shù)據(jù)庫的用戶名〔odbc〕和密碼〔odbc〕,才能登錄到指定的數(shù)據(jù)庫。②在對(duì)話框資源中添加控件翻開“資源視圖〞,展開當(dāng)前工程資源下的“Dialog〞節(jié)點(diǎn),雙擊IDD_S11_1_FORM,翻開對(duì)話框編輯器,按以下步驟添加控件?!裉砑右粋€(gè)標(biāo)題靜態(tài)文本框,Caption屬性為:學(xué)生信息●為student表的每個(gè)字段添加相應(yīng)的靜態(tài)文本〔Statictext〕和編輯框〔Editbox〕控件,靜態(tài)文本的Caption屬性分別為:學(xué)號(hào)、姓名、系別、專業(yè)、班級(jí),編輯框控件的ID分別為IDC_SNO、IDC_SNAME、IDC_SDEPT、IDC_SPECIAL、IDC_SCLASS,如圖11-28所示。
翻開“類視圖〞,選擇“CS11_1View〞類,定位到數(shù)據(jù)交換函數(shù)DoDataExchange,添加以下代碼。提示:在VS2023中不能通過類向?qū)⒖丶陀涗浖械淖兞筷P(guān)聯(lián)。voidCS11_1View::DoDataExchange(CDataExchange*pDX){ CRecordView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CS11_1View) DDX_FieldText(pDX,IDC_SNO,m_pSet->m_sno,m_pSet); DDX_FieldText(pDX,IDC_SNAME,m_pSet->m_sname,m_pSet); DDX_FieldText(pDX,IDC_SCLASS,m_pSet->m_sclass,m_pSet); DDX_FieldText(pDX,IDC_SDEPT,m_pSet->m_sdept,m_pSet); DDX_FieldText(pDX,IDC_SPECIAL,m_pSet->m_special,m_pSet); //}}AFX_DATA_MAP}
③將Edit控件和數(shù)據(jù)集中的字段關(guān)聯(lián)
重新編譯運(yùn)行此程序,結(jié)果如圖11-29所示。程序現(xiàn)在可以顯示stu_score數(shù)據(jù)庫中student表的當(dāng)前記錄,并可通過界面上端的工具欄按鈕進(jìn)行數(shù)據(jù)庫記錄的導(dǎo)航,包括移動(dòng)第一條、上一條、下一條、最后一條記錄等,當(dāng)記錄不能移動(dòng)時(shí),
相應(yīng)按鈕自動(dòng)變灰,防止誤操作。①添加查找功能翻開“資源視圖〞,展開Menu菜單資源,雙擊“IDR_MAINFRAME〞,翻開菜單編輯器,在“記錄〞和“查看〞之間添加一個(gè)“查找(&S)〞菜單,并在其下面增加兩個(gè)菜單項(xiàng),ID分別為ID_FIND_STU和ID_FIND_STU_ALL,Caption分別為“查找學(xué)生(&C)〞和“所有學(xué)生信息(&A)〞,接下來,為該工程添加一個(gè)對(duì)話框資源用于輸入查找學(xué)生的學(xué)號(hào)。翻開“資源視圖〞,展開工程資源,在“Dialog〞節(jié)點(diǎn)的按右鍵,在彈出的快捷菜單中,選擇“添加資源〞菜單項(xiàng),在彈出的“添加資源〞對(duì)話框中選擇Dialog,單擊“新建〞按鈕,完成對(duì)話框資源的添加。選中該對(duì)話框,修改ID為IDD_FIND_STU。在對(duì)話框上添加一個(gè)靜態(tài)文本、一個(gè)編輯框和兩個(gè)按鈕控件,其屬性設(shè)置如表11-3所示,設(shè)計(jì)的最終效果如圖11-31所示翻開“類向?qū)Ж暎c(diǎn)擊“添加類〞按鈕,為對(duì)話框資源IDD_FIND_STU添加一個(gè)新類CFindStuDialog,基類為CDialog類,如圖11-32所示,點(diǎn)擊“完成〞,關(guān)閉“添加類向?qū)Ж晫?duì)話框。在“類向?qū)Ж晫?duì)話框中,為編輯框控件IDC_FIND_STU_SNO添加成員變量m_find_stu_sno,類別為Value,類型為CString,如圖11-33所示。在“MFC類向?qū)Ж晫?duì)話框中,選擇CS11_1View類,在“對(duì)象ID〞中,為“查找學(xué)生〞菜單項(xiàng)ID_FIND_STU,添加COMMAND和UPDATE_COMMAND_UI消息響應(yīng)函數(shù)OnFindStu和OnUpdateFindStu。為“所有學(xué)生信息〞菜單項(xiàng)ID_FIND_STU_ALL,添加COMMAND和UPDATE_COMMAND_UI消息響應(yīng)函數(shù)OnFindStuAll和OnUpdateFindStuAll。重新編譯運(yùn)行應(yīng)用程序,在“查找〞菜單下選擇“查找學(xué)生〞,彈出如圖11-35所示對(duì)話框,輸入要查找的學(xué)生學(xué)號(hào),如002,如果在記錄集中找到了相應(yīng)的記錄,那么顯示此記錄,否那么,彈出消息框顯示“沒有找到該學(xué)生信息〞。②添加增加功能翻開“資源視圖〞中Menu資源,雙擊IDR_MAINFRAME翻開菜單資源編輯器。在“記錄〞菜單下添加菜單項(xiàng),Caption為“添加記錄(&)〞,ID為ID_RECORD_APPEND,如圖11-36所示。在CS11_1View類中添加一個(gè)保護(hù)類型的成員變量m_bAddFlag,用于標(biāo)記當(dāng)前是否處于添加狀態(tài),翻開S11_1View.h文件,在類定義的保護(hù)局部添加如下代碼:BOOLm_bAddFlag;在CS11_1View類的構(gòu)造函數(shù)中,將其初始化為FALSE:m_bAddFlag=FALSE;翻開“類向?qū)Ж晫?duì)話框,選擇CS11_1View類,為“添加記錄〞菜單項(xiàng)ID_RECORD_APPEND添加COMMAND和UPDATE_COMMAND_UI消息響應(yīng)函數(shù)。點(diǎn)擊“虛虛數(shù)〞標(biāo)簽,選擇OnMove,點(diǎn)擊“添加函數(shù)〞按鈕,重寫OnMove虛函數(shù),如圖11-37所示。11.1數(shù)據(jù)庫訪問方式11.2ODBC訪問SQLServer技術(shù)
11.3DAO訪問Access數(shù)據(jù)庫
11.4ADO訪問Access數(shù)據(jù)庫
主要內(nèi)容11.3DAO訪問Access數(shù)據(jù)庫11.3.1記錄集與記錄視11.3.2增強(qiáng)的數(shù)據(jù)庫管理功能11.3.3DAO應(yīng)用舉例DAO引入了一種在ODBC體系中沒有的新記錄集類型:表類型記錄集。它是一個(gè)完整的數(shù)據(jù)庫表的直接視圖,我們只能對(duì)Access數(shù)據(jù)庫中的表使用表類型記錄集。表類型記錄集有下面一些區(qū)別于快照和動(dòng)態(tài)記錄集的特征。〔1〕函數(shù)CDaoRecordset::GetRecordCount返回一個(gè)近似的記錄數(shù),這個(gè)數(shù)能反映其他用戶增加或刪除的記錄?!?〕不能用CDaoRecordset的函數(shù)訪問一個(gè)記錄的絕對(duì)或百分比位置?!?〕CDaoRecordset::Seek函數(shù)通過關(guān)鍵字段值定位到一條記錄,但首先要調(diào)用CdaoRecordset::SetCurrentIndex函數(shù)選擇索引字段?!?〕如果往表類型記錄集中添加一條記錄,該記錄的位置由當(dāng)前索引排列的順序決定。表類型記錄集在很大程度上背離了ODBC和SQL,也就是說可以不通過查詢而選擇一條單獨(dú)的記錄;也可以通過索引找到一條記錄,然后用另外一個(gè)索引來順序移動(dòng),這和dBASE或者FoxPro的編程思路類似。
11.3.1記錄集與記錄視11.3.2增強(qiáng)的數(shù)據(jù)庫管理功能VisualC++的MFC中包含的DAO類與ODBC類非常相似,前面介紹的主要ODBC類:CDatabase、CRecordset和CrecordView,在DAO類中都有與之相對(duì)應(yīng)的類:CDaoDatabase、CDaoRecordset和CDaoRecordView,其中封裝的成員變量和函數(shù)也類似,但它們比對(duì)應(yīng)的ODBC類封裝了更多的成員函數(shù)。DAO增加了一個(gè)名為CDaoWorkspace的類,當(dāng)開始跟蹤事務(wù)時(shí),DAO通過CDaoWorkspace類給出了較好的粒度〔Granularity〕。下面介紹DAO類比ODBC類新增的內(nèi)容。11.3.3DAO應(yīng)用舉例在了解了MFCDAO類以后,下面給出一個(gè)DAO應(yīng)用實(shí)例,這個(gè)實(shí)例所采用的數(shù)據(jù)庫是MicrosoftAccess。因?yàn)樵贠DBC訪問數(shù)據(jù)庫的應(yīng)用實(shí)例中已經(jīng)向大家介紹了根本的數(shù)據(jù)庫操作〔如數(shù)據(jù)的添加、修改、刪除等〕,本節(jié)的實(shí)例主要集中在DAO新增的功能〔如新建數(shù)據(jù)表〕的介紹,使讀者體會(huì)到DAO的優(yōu)勢(shì)所在。1.應(yīng)用實(shí)例概述本實(shí)例使用Access數(shù)據(jù)庫,首先需要新建一個(gè)Access數(shù)據(jù)庫test,但并不建立任何數(shù)據(jù)表,也就是建立一個(gè)沒有數(shù)據(jù)表的數(shù)據(jù)庫。在應(yīng)用程序中新建數(shù)據(jù)表,也可以刪除數(shù)據(jù)表。2.創(chuàng)立應(yīng)用程序〔1〕啟動(dòng)VS2023,選擇“文件|新建|工程…〞菜單項(xiàng),翻開“新建工程〞對(duì)話框,選擇應(yīng)用程序模板為“MFC應(yīng)用程序〞,在“名稱〞框中輸入應(yīng)用程序名S11_3,在“位置〞框中輸入應(yīng)用程序保存的位置,如圖11-49所示。2.創(chuàng)立應(yīng)用程序
①單擊“確定〞按鈕,在彈出的“MFC應(yīng)用程序向?qū)Ж晫?duì)話框中,選擇工程類型為“基于對(duì)話框〞,如圖11-50所示。②其余選項(xiàng)采用默認(rèn)值,點(diǎn)擊“完成〞按鈕,生成應(yīng)用程序框架。2.創(chuàng)立應(yīng)用程序〔2〕在對(duì)話框界面上添加控件資源翻開“資源視圖〞,展開對(duì)話框資源,雙擊Dialog下的IDD_S11_3_DIALOG,翻開對(duì)話框編輯器,按下面步驟在對(duì)話框中修改或者添加控件。①修改IDOK按鈕屬性,將其Caption屬性設(shè)為“新建表〞2.創(chuàng)立應(yīng)用程序②增加兩個(gè)RadioButton控件和一個(gè)CheckBox控件,兩個(gè)RadioButton控件的ID分別為IDC_NEW_TABLE和IDC_DELETE_TABLE,Caption屬性分別為“新建表〞和“刪除表〞,CheckBox控件ID為IDC_IS_KEY,Caption屬性為“是否不為空〞。③增加兩個(gè)EditBox控件:ID號(hào)分別為IDC_NEWTABLE_NAME,IDC_FIELD_NAME,增加兩個(gè)Combobox控件,一個(gè)ID為IDC_EXISTTABLE_NAME,并且將其位置和IDC_NEWTABLE_NAME位置重合,另一個(gè)ID為IDC_FIELD_TYPE,Type屬性為:“DropList〞,Data屬性為:“文本;數(shù)字;〞。添加控件后的對(duì)話框如圖11-52所示,注意重合的控件只能看到最前端一個(gè)。2.創(chuàng)立應(yīng)用程序2.創(chuàng)立應(yīng)用程序〔4〕利用“類向?qū)Ж暈榭丶砑酉㈨憫?yīng)函數(shù)翻開“類向?qū)Ж?,在“類名〞選擇CS11_3Dlg,在“命令〞標(biāo)簽下的“對(duì)象ID〞中列出了剛剛添加控件的ID,選擇相應(yīng)的控件ID添加消息響應(yīng)函數(shù),需要添加的消息響應(yīng)函數(shù)如表11-5所示。2.創(chuàng)立應(yīng)用程序2.創(chuàng)立應(yīng)用程序
str.TrimLeft(); str.TrimRight(); if(str=="新建表") {sqlcode="createtable"+m_newtable_name+"("+m_field_name;if(m_field_type.GetCurSel()==1)sqlcode+="char(10)";if(m_field_type.GetCurSel()==0)sqlcode+="int";if(m_is_key.GetCheck()==1)sqlcode+="notnull";sqlcode+=")";m_db.Execute(sqlcode,dbFailOnError);m_existtable_name.AddString(m_newtable_name);MessageBox("新建表"+m_newtable_name+"成功!");m_newtable_name="";m_field_name="";m_is_key.SetCheck(0);UpdateData(FALSE); }2.創(chuàng)立應(yīng)用程序
if(str=="刪除表")
{CStringcurtable;
if(m_existtable_name.GetCount()!=0)
{m_existtable_name.GetLBText(m_existtable_name.GetCurSel(),
curtable);
sqlcode="droptable"+curtable;
m_db.Execute(sqlcode,dbFailOnError);
m_existtable_name.DeleteString(m_existtable_name.GetCurSel());
m_existtable_name.SetCurSel(0);
MessageBox("刪除表"+curtable+"成功!");
}
elseMessageBox("當(dāng)前沒有表可刪除!");
}
m_db.Close();
//CDialog::OnOK();
}2.創(chuàng)立應(yīng)用程序
voidCS11_3Dlg::OnDeleteTable()
{
//TODO:Addyourcontrolnotificationhandlercodehere
//隱藏或顯示相應(yīng)控件
GetDlgItem(IDC_EXISTTABLE_NAME)->ShowWindow(TRUE);
GetDlgItem(IDC_NEWTABLE_NAME)->ShowWindow(FALSE);
GetDlgItem(IDC_FIELD_NAME)->ShowWindow(FALSE);
GetDlgItem(IDC_FIELD_TYPE)->ShowWindow(FALSE);
GetDlgItem(IDC_IS_KEY)->ShowWindow(FALSE);
GetDlgItem(IDC_STATIC1)->ShowWindow(FALSE);
GetDlgItem(IDC_STATIC2)->ShowWindow(FALSE);
GetDlgItem(IDOK)->SetWindowText("刪除表");
GetDlgItem(IDOK)->EnableWindow(TRUE);
m_newtable_name="";
m_field_name="";
m_is_key.SetCheck(0);
UpdateData(FALSE);
}2.創(chuàng)立應(yīng)用程序
voidCS11_3Dlg::OnNewTable()
{
//TODO:Addyourcontrolnotificationhandlercodehere
//隱藏或顯示相應(yīng)控件
GetDlgItem(IDC_EXISTTABLE_NAME)->ShowWindow(FALSE);
GetDlgItem(IDC_NEWTABLE_NAME)->ShowWindow(TRUE);
GetDlgItem(IDC_FIELD_NAME)->ShowWindow(TRUE);
GetDlgItem(IDC_FIELD_TYPE)->ShowWindow(TRUE);
GetDlgItem(IDC_IS_KEY)->ShowWindow(TRUE);
GetDlgItem(IDC_STATIC1)->ShowWindow(TRUE);
GetDlgItem(IDC_STATIC2)->ShowWindow(TRUE);
GetDlgItem(IDOK)->SetWindowText("新建表");
GetDlgItem(IDOK)->EnableWindow(FALSE);
}2.創(chuàng)立應(yīng)用程序
voidCS11_3Dlg::OnChangeFieldName()
{
//TODO:IfthisisaRICHEDITcontrol,thecontrolwillnot
//sendthisnotificationunlessyouoverridetheCDialog::OnInitDialog()
//functionandcallCRichEditCtrl().SetEventMask()
//withtheENM_CHANGEflagORedintothemask.
//TODO:Addyourcontrolnotificationhandlercodehere
UpdateData(TRUE);
m_field_name.TrimLeft();
m_field_name.TrimRight();
GetDlgItem(IDOK)->EnableWindow(TRUE);
}
voidCS11_3Dlg::OnChangeNewtableName()
{
//TODO:IfthisisaRICHEDITcontrol,thecontrolwillnot
//sendthisnotificationunlessyouoverridetheCDialog::OnInitDialog()
//functionandcallCRichEditCtrl().SetEventMask()
//withtheENM_CHANGEflagORedintothemask.
//TODO:Addyourcontrolnotificationhandlercodehere
UpdateData(TRUE);
m_newtable_name.TrimLeft();
m_newtable_name.TrimRight();
}2.創(chuàng)立應(yīng)用程序2.創(chuàng)立應(yīng)用程序11.1數(shù)據(jù)庫訪問方式11.2ODBC訪問SQLServer技術(shù)
11.3DAO訪問Access數(shù)據(jù)庫
11.4ADO訪問Access數(shù)據(jù)庫
主要內(nèi)容11.4ADO訪問Access數(shù)據(jù)庫在掌握了MFC的ODBC編程技術(shù)〔CDatabase和CRecordset〕和DAO以后,學(xué)習(xí)ADO編程就十分容易了,因?yàn)锳DO也是提供了三個(gè)主要的對(duì)象來完成數(shù)據(jù)庫的訪問。〔1〕Connection〔連接對(duì)象〕〔2〕Command〔命令對(duì)象〕〔3〕Recordset〔記錄集對(duì)象〕
1.使用預(yù)處理指令#import2.使用MFC中的CIDispatchDriver3.直接使用COM對(duì)象提供的API函數(shù)11.4ADO訪問Access數(shù)據(jù)庫1.使用預(yù)處理指令#import在工程stdAfx.h文件的開頭,所有include指令后,參加以下編譯預(yù)處理指令:#import"C:\ProgramFiles\CommonFiles\System\ADO\msado15.dll"no_namespacerename("EOF","EndOfFile")這樣在編譯時(shí),VC++會(huì)讀出msado15.dll中的類型庫信息,自動(dòng)生成該類型庫的頭文件msado15.tlh和實(shí)現(xiàn)文件msado15.tli。這兩個(gè)文件定義了ADO的所有對(duì)象和方法,以及一些枚舉常量。
2.使用MFC中的CIDispatchDriver
通過讀取msado15.dll的類型庫信息,建立一個(gè)COleDispatchDriver類的派生類,然后通過它調(diào)用ADO對(duì)象。
3.直接使用COM對(duì)象提供的API函數(shù)下面的代碼就是用COMAPI函數(shù)創(chuàng)立一個(gè)ADO連接對(duì)象:CLSIDclsid;HRESULThr=::CLSIDFromProgID(L"ADODB.Connection",&clsid);if(FAILED(hr)){...}::CoCreateInstance(clsid,NULL,CLSCTX_SERVER,IID_IDispatch,(void**)&pDispatch);if(FAILED(hr)){...}以上三種方法,第一和第二種類似,第一種簡(jiǎn)單,適合初學(xué)者,第三種編程麻煩,但是效率高,程序大小也小,并且對(duì)ADO的控制能力也最強(qiáng)。11.4.2使用#import的編程步驟
下面討論在VisualC++中用import方法進(jìn)行ADO數(shù)據(jù)庫編程的具體過程。1.生成應(yīng)用程序框架并初始化OLE/COM庫環(huán)境首先創(chuàng)立標(biāo)準(zhǔn)MFC應(yīng)用程序框架,選擇單文檔應(yīng)用程序,然后在應(yīng)用程序類的InitInstance成員函數(shù)中初始化OLE/COM庫,添加以下代碼:::CoInitialize(NULL);//初始化OLE/COM庫環(huán)境在應(yīng)用程序類的ExitInstance成員函數(shù)中添加釋放程序占用COM資源的代碼:::CoUninitialize();
2.導(dǎo)入ADO庫文件
由于ADO類的定義是作為一種資源存儲(chǔ)在ADODLL(msado15.dll〕中,在使用ADO之前,必須在工程stdafx.h文件的所有Include后面,導(dǎo)入ADO庫文件,以便編譯器能正確編譯,代碼如下:#import"C:\ProgramFiles\commonfiles\system\ado\msado15.dll"no_namespacerename("EOF","adoEOF")參數(shù)no_namespace說明ADO對(duì)象不使用命名空間,如何使用命名空間,那么參數(shù)為:rename_namespace("AdoNS")。參數(shù)rename是將ADO中的EOF〔文件結(jié)束〕更名為adoEOF,以免和自己的EOF沖突。
3.利用智能指針進(jìn)行數(shù)據(jù)庫操作
ADO庫包含了三個(gè)智能指針:〔1〕_ConnectionPtr:用來創(chuàng)立一個(gè)數(shù)據(jù)連接或執(zhí)行一條不返回任何結(jié)果的SQL語句?!?〕_CommandPtr返回一個(gè)記錄集,它提供了一種簡(jiǎn)單方法來執(zhí)行返回記錄集的存儲(chǔ)過程或SQL語句。提示:在使用_CommandPtr接口時(shí),可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用連接字符串?!?〕_RecordsetPtr是一個(gè)記錄集對(duì)象,提供了對(duì)記錄集的控制,如記錄鎖定、游標(biāo)控制等。利用智能指針進(jìn)行數(shù)據(jù)操作主要有以下幾個(gè)步驟:①在視圖類中添加三個(gè)智能指針的數(shù)據(jù)成員:_ConnectionPtr m_pConnection;_RecordsetPtr m_pRecordset;_CommandPtr m_pCommand;②在視圖類的初始化更新函數(shù)中對(duì)三個(gè)智能指針進(jìn)行初始化:m_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指針m_pRecordset.CreateInstance(_uuidof(Recordset)); //初始化Recordset指針m_pCommand.CreateInstance(_uuidof(Command)); //初始化Command指針CreateInstance也提供相應(yīng)的字符串版本來進(jìn)行智能指針的初始化,如://m_pCommand.CreateInstance("ADODB.Command");③如果要連接Access數(shù)據(jù)庫stuscore.mdb,那么可調(diào)用m_pConnection的Open函數(shù):m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=stuscore.mdb;〞,"","",0);3.利用智能指針進(jìn)行數(shù)據(jù)庫操作④下面的代碼是得到一個(gè)記錄集:CStringstrSql="select*fromstuinfo";BSTRbstrSQL=strSql.AllocSysString();m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText);⑤下面的代碼是對(duì)數(shù)據(jù)集進(jìn)行遍歷:while(!m_pRecordset->adoEOF){//方法1:獲取記錄字段值_variant_tTheValue; //VARIANT數(shù)據(jù)類型//獲取學(xué)生姓名TheValue=m_pRecordset->GetCollect("STUNAME"); /*//方法2:獲取記錄字段值_bstr_tTheValue1=m_pRecordset->Fields->GetItem("BIG_NAME")->Value;
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版人工智能技術(shù)研發(fā)與應(yīng)用合同15篇
- 常州2025版二手房過戶稅費(fèi)處理與過戶手續(xù)辦理合同2篇
- 二零二五版智慧城市建設(shè)合作合同范本2篇
- 二零二五版在線教育管理系統(tǒng)定制開發(fā)合同3篇
- 二零二五版ISO9001質(zhì)量管理體系認(rèn)證與質(zhì)量管理體系審核與監(jiān)督合同3篇
- 水電工程2025年度施工安全評(píng)估合同2篇
- 二零二五版LED顯示屏戶外廣告位租賃合同協(xié)議3篇
- 二零二五年海鮮餐飲業(yè)特色菜品開發(fā)與銷售合同3篇
- 二零二五年度虛擬現(xiàn)實(shí)游戲開發(fā)電子合同承諾3篇
- 二零二五版智能零售企業(yè)兼職銷售員勞動(dòng)合同3篇
- DLT 5285-2018 輸變電工程架空導(dǎo)線(800mm以下)及地線液壓壓接工藝規(guī)程
- 新員工入職培訓(xùn)測(cè)試題附有答案
- 勞動(dòng)合同續(xù)簽意見單
- 大學(xué)生國家安全教育意義
- 2024年保育員(初級(jí))培訓(xùn)計(jì)劃和教學(xué)大綱-(目錄版)
- 河北省石家莊市2023-2024學(xué)年高二上學(xué)期期末考試 語文 Word版含答案
- 企業(yè)正確認(rèn)識(shí)和運(yùn)用矩陣式管理
- 分布式光伏高處作業(yè)專項(xiàng)施工方案
- 陳閱增普通生物學(xué)全部課件
- 檢驗(yàn)科主任就職演講稿范文
- 人防工程主體監(jiān)理質(zhì)量評(píng)估報(bào)告
評(píng)論
0/150
提交評(píng)論