郭 強
(西安電子科技大學 電子工程學院,陜西 西安710071)
數(shù)據(jù)庫、互聯(lián)網(wǎng)技術作為當今兩大熱門計算技術,兩者息息相關,所以實現(xiàn)對數(shù)據(jù)庫的訪問就顯得尤為重要。作為數(shù)據(jù)庫開發(fā)的前端工具,文中選擇Visual C++SDK(Software Development Kit)。該平臺提供了多種數(shù)據(jù)庫訪問技術—ODBC API、MFC ODBC、DAO、OLE DB、ADO等。這些技術各有特點,他們提供了簡單、靈活、訪問速度快、可擴展性好的開發(fā)技術。與上述其他技術相比,ADO基于OLE DB訪問接口,采用面向?qū)ο蠓椒?,對接口進行封裝,使程序開發(fā)得到簡化。ADO技術屬于數(shù)據(jù)庫訪問的高層接口。
ADO(ActiveX Data Ob1ject,ActiveX數(shù)據(jù)對象)是微軟提供的一種面向?qū)ο蟆⑴c語言無關的數(shù)據(jù)訪問應用編程接口。之前使用的OLE DB API,實現(xiàn)了對數(shù)據(jù)庫的底層訪問,但它僅支持C/C++,而ADO是對OLE DB API進行封裝,實現(xiàn)了對數(shù)據(jù)庫的高層訪問,同時也提供適用于多種編程語言的訪問技術,包括Visual C++、Visual Basic、Visual J++等。由于ADO提供了訪問自動化接口,所以它也支持描述的腳本語言,如VBScript、JavaScript。
在ADO的對象結構中,對象與對象之間的層次結構不夠明顯。在模型層次上,ADO基于OLE DB技術,但在應用層次上,又高于OLE DB技術,因為它簡化了對對象模型的操作,并且不依賴對象之間的相互層次關系。在多數(shù)情況下,只需關心所要創(chuàng)建和使用的對象,并不需要了解其父對象是否存在。所以,在實際編程應用中,不必關心對象的構造順序和構造層次。ADO繼承了OLE DB訪問數(shù)據(jù)源的高效性,幾乎可以訪問所有關系型數(shù)據(jù)源和非關系型數(shù)據(jù)源,使得應用程序具有良好的通用性和靈活性[1]。
圖1 ADO訪問數(shù)據(jù)庫的結構
ADO被設計來繼承微軟早期的數(shù)據(jù)訪問對象層,包括RDO(Remote Data Objects)和DAO(Data Access Objects),ADO的頂層對象包括連接、記錄集、命令、記錄、流、錯誤、字段、參數(shù)和屬性等[2]。
Connection對象用于表示與數(shù)據(jù)源的連接,通過“連接”,可以從應用程序訪問數(shù)據(jù)源,連接是交換數(shù)據(jù)所必需的環(huán)境。通過如Microsoft IIS(Internet Information Server)作為媒介,應用程序可直接或間接訪問數(shù)據(jù)源。
Recordset對象用于處理數(shù)據(jù)源表格集,獲取并修改數(shù)據(jù)。如果命令是在表中按信息行返回數(shù)據(jù)的查詢,則這些行將會存儲在本地。對象模型將該存儲體現(xiàn)為Recordset對象。但是,不存在僅代表單獨一個Recordset行的對象。記錄集是在行中檢查和修改數(shù)據(jù)的主要方法。對存儲在本地的行的操作也就是對所取得的表中每一條記錄的操作。
通過已建立的連接發(fā)出的“命令”可以用某種方式來操作數(shù)據(jù)源,經(jīng)常用到的方法是Execute。該方法可執(zhí)行Command對象的CommandText屬性中指定的查詢、SQL語句或存儲過程。如果CommandText屬性指定以行返回的查詢,執(zhí)行產(chǎn)生的任何結果都將存儲在新的Recordset對象中。如果此命令不是以行返回的查詢,提供者將返回關閉的Recordset對象。在文中的實例中,Execute對SQL Sever操作有Update、Insert、Delete等。
Error對象用于獲得所產(chǎn)生錯誤的詳細信息。錯誤隨時可在應用程序中發(fā)生,通常是由于無法建立連接、無法執(zhí)行命令或無法對某些狀態(tài)的對象進行操作。對錯誤的獲取和處理利用_com_error類來實現(xiàn),通過對異常的捕獲,可以輕易地定位錯誤的發(fā)生,提高改正錯誤的效率。
Parameter對象用于對傳遞給數(shù)據(jù)源的命令賦參數(shù)值。通常,命令需要的變量部分即“參數(shù)”可以在命令發(fā)布之前進行更改。例如,可重復發(fā)出相同的數(shù)據(jù)檢索命令,但每次均可更改指定的檢索信息。參數(shù)對于函數(shù)活動相同的可執(zhí)行命令較有用,這樣就可以了解命令的功能,但不必知道它是如何工作的。例如,發(fā)出一項銀行過戶命令,資金由一方賬戶支付給另一方,可將要過戶的金額設置為參數(shù)。
圖2 ADO對象的編程模型
簡單的數(shù)據(jù)庫訪問技術對ADO事件[3]概念涉及較少,但這并不代表可以忽略ADO事件的作用。微軟最初的ADO應用并不包含事件概念,直到ADO2.0,才將其引入編程模型,它的出現(xiàn),為實現(xiàn)應用程序中包含多個異步任務提供了手段。
ADO事件模型支持某些同步和異步的ADO操作,ADO對象模型無法顯式體現(xiàn)事件,只能在調(diào)用事件處理程序例程時表現(xiàn)出來。事件實際就是對在應用程序中定義的事件處理程序例程的調(diào)用。由于ADO支持異步操作,所以,在操作完成之后被調(diào)用的事件處理程序尤其重要。
事件分為兩類,ConnectionEvent和RecordsetEvent。ConnectionEvent類從屬于Connection對象的操作,在連接開始或結束時,或在Command被執(zhí)行時,將引發(fā)該類事件;RecordsetEvent類從屬于Recordset對象的操作,在Recordset對象的記錄中定位、更改其中的字段時,或在Recordset作任何修改時,將引發(fā)該類事件。
ADO事件的事件類型有Will事件,Complete事件和其他事件。Will事件是在操作開始之前調(diào)用的事件處理程序,它使應用者有機會檢查或修改操作參數(shù),決定是取消操作還是允許完成該操作。Complete事件是在操作完成之后調(diào)用的事件處理程序,它向應用程序發(fā)出操作已結束的通知,除此之外,當掛起的操作被Will事件處理程序取消時,該事件處理程序也會收到通知。至于事件處理程序如何共同工作,文中涉及的實例中并未體現(xiàn),不作深入剖析。
使用ActiveX控件是開發(fā)ADO應用程序的簡單方法,僅 需Microsoft ADO Data Control和Microsoft DataGrid Control兩個控件就可實現(xiàn)。ADO Data控件實現(xiàn)了ADO對數(shù)據(jù)源(任何OLE DB數(shù)據(jù)源)的快速連接和訪問;數(shù)據(jù)捆綁控件DataGrid將ADO Data控件的訪問結果在界面上顯示出來。
圖3 ADO Data控件控制屬性設置對話框
圖3所示的設置對話框主要用來設置與數(shù)據(jù)源連接有關的屬性。連接數(shù)據(jù)源的方式有3種,分別使用數(shù)據(jù)連接文件、使用ODBC數(shù)據(jù)源和使用連接字符串描述的數(shù)據(jù)源,這里選擇第3種方式實現(xiàn)。連接字符串中包含了連接數(shù)據(jù)源的信息,這個字符串可以通過點擊“Build”按鈕設置數(shù)據(jù)鏈接屬性來完成。接下來,是對記錄源的定義。打開“RecordSource”選項卡,設置命令類型和命令文本。這些對ADO Data控件簡單的設置即實現(xiàn)了ADO與SQL Server數(shù)據(jù)庫的連接。最后,要將獲得的結果在DataGrid控件界面上進行顯示。要實現(xiàn)這個目標,必須在這兩個控件之間建立關聯(lián),方法是設置DataGrid屬性中的DataSource為ADO Data控件的ID,如圖4所示。
圖4 DataGrid控件屬性設置對話框
經(jīng)過對兩個控件屬性的設置,不寫任何代碼就可以產(chǎn)生一個完整并且有實際意義的應用程序。這種方式簡潔、易操作,但也有不足之處。它增加了許多不必要的系統(tǒng)資源開銷,例如當要對數(shù)據(jù)源進行查詢或者操作時,這種方式每次查詢或者操作都會建立一個與數(shù)據(jù)源的連接,這種重復連接會降低系統(tǒng)的性能,而且這種方法只適用于將查詢結果顯示出來,對添加或者更新等要求較高的應用就有些力不從心了。
為最大限度發(fā)揮ADO技術高速靈活的特點,讓應用者完全實現(xiàn)對數(shù)據(jù)庫的控制,利用ADO對象開發(fā)應用程序,無疑是最完美的選擇。使用ADO對象開發(fā)應用程序[4],有以下步驟:
(1)導入ADO文件。為使編譯器能正確編譯ADO,首先要導入工程所需要的動態(tài)鏈接庫(DLL)文件msado15.dll。在stdafx.h文件里直接使用#import引入,代碼如下
ADO類的定義是作為一種資源存儲在指定的動態(tài)鏈接庫文件中,在其內(nèi)部稱為類型庫。類型庫描述了自治接口,以及C++使用的COM Vtable接口。使用#import指令,在運行時Visual C++會從動態(tài)鏈接庫中讀取這個類型庫,并以此創(chuàng)建一組C++頭文件,這些頭文件具有.tli和.tlh擴展名,可以在工程目錄下找到這兩個文件,在C++程序代碼中調(diào)用的ADO類都要在這些文件中定義。
(2)初始化OLE/COM庫環(huán)境。ADO是一個用于存儲數(shù)據(jù)源的COM組件,因此在調(diào)用前,必須初始化OLE/COM庫環(huán)境。
接下來就是取得一個可以進行操作的記錄集對象。定義一個指向Recordset對象的指針,并為其創(chuàng)建對象實例,利用Open方法打開結果記錄集
(4)對獲取的數(shù)據(jù)進行操作。這一步主要是在Visual C++平臺下對SQL Server數(shù)據(jù)庫的操作,包括插入記錄、修改記錄、更新記錄、刪除記錄等,相關的操作命令可參閱有關手冊。操作中,需要注意的一點是對記錄集的判空命令的使用,只有恰當?shù)厥褂门锌彰畈拍軠蚀_的對記錄集進行操作,避免操作異常及操作錯誤的出現(xiàn)。
(5)關閉記錄集、關閉連接。對數(shù)據(jù)庫操作完畢后,先關閉記錄集,后關閉連接,同時釋放建立的對象實例。在程序的實例初始化時,對OLE/COM組件進行了初始化,加載了ADO運行所需要的動態(tài)鏈接庫文件的類庫。相應地,在程序終止時,要使用CoUninitialize()關閉當前線程的組件對象模型庫,卸載所有動態(tài)鏈接庫載入的類庫。
這種方法充分利用了ADO的資源,對記錄集的操作可隨應用者的意圖完成,實現(xiàn)了ADO訪問及操作數(shù)據(jù)庫數(shù)據(jù)的靈活性。
對ADO的應用結構和對象模型做了介紹,詳細論述了ADO的工作原理和對數(shù)據(jù)庫的訪問,實現(xiàn)了與數(shù)據(jù)源的連接和對記錄集的操作。
ADO作為微軟著重推出的數(shù)據(jù)庫訪問接口技術,得取了廣范應用。它定位于高層訪問,對底層控制透明,為使用者在建立應用程序的方式上提供了較大的方便性和靈活性。ADO技術的優(yōu)越性,正使其逐步替代ODBC等數(shù)據(jù)庫訪問技術,成為事實上的數(shù)據(jù)庫訪問標準。
[1] 鄭章,陳剛,張勇,等.Visual C++6.0數(shù)據(jù)庫開發(fā)技術[M].北京:機械工業(yè)出版社,1999.
[2] 劉增軍,向為,孫廣富.基于ADO的數(shù)據(jù)庫開發(fā)技術研究[J].科學技術與工程,2007,7(5):747-752.
[3] 曹紅根,丁永.數(shù)據(jù)庫應用系統(tǒng)開發(fā)實例[M].北京:清華大學出版社,2008.
[4] 徐楓,馬國之,劉良旭.基于ADO技術的數(shù)據(jù)庫訪問研究與實現(xiàn)[J].計算機工程與設計,2004,25(1):107-110.