直播中
8.1 ADO的定義
ADO是一個(gè)相當(dāng)簡(jiǎn)單的思想,一種讓你僅用一種方式去訪問(wèn)數(shù)據(jù)的思想。ADO不算一個(gè)新思想,僅是采用現(xiàn)有的數(shù)據(jù)庫(kù)訪問(wèn)技術(shù),并將其融合而形成的一種適應(yīng)現(xiàn)在和未來(lái)需要的新東西。適應(yīng)未來(lái)的需求是一件十分重要的事。許多其他的技術(shù),比如DAO和ODBC,在一些應(yīng)用程序的開發(fā)過(guò)程中是可以接受的,然而隨著Internet的興起也出現(xiàn)了其自身的一些問(wèn)題。
在許多情況下,傳統(tǒng)的數(shù)據(jù)存取方法看上去能解決一些關(guān)于兩層客戶/服務(wù)器系統(tǒng)的問(wèn)題,但要求與數(shù)據(jù)之間要保持一種永久性的連接,并要提供強(qiáng)大的功能,比如快速響應(yīng)的查詢、數(shù)據(jù)容易修改等。在Internet領(lǐng)域,現(xiàn)在必須考慮到Web無(wú)狀態(tài)性本質(zhì),和潛在的眾多可以訪問(wèn)Web站點(diǎn)的用戶。要與數(shù)據(jù)建立永久的連接是不現(xiàn)實(shí)的,因此必須在設(shè)計(jì)應(yīng)用程序時(shí)考慮這些因素。
那么,OLD DB和ADO確切地講到底是什么?讓我們與一些已有的數(shù)據(jù)存取技術(shù)做比較后再來(lái)回答這個(gè)問(wèn)題。如果讀者曾經(jīng)接觸過(guò)數(shù)據(jù)庫(kù)編程,或許比較熟悉ODBC和RDO。開放數(shù)據(jù)庫(kù)連接(ODBC)是允許訪問(wèn)關(guān)系數(shù)據(jù)庫(kù)(比如Access和SQL Server)的應(yīng)用程序編程接口(API)。正因?yàn)槭且粋€(gè)API,許多程序員,特別是Visual Basic領(lǐng)域的程序員,發(fā)現(xiàn)它使用起來(lái)很復(fù)雜。遠(yuǎn)程數(shù)據(jù)對(duì)象(RDO)是位于ODBC上層的ActiveX對(duì)象,可以提供ODBC的所有功能,并且使用起來(lái)比較簡(jiǎn)單。
可以將OLE DB等同于ODBC,ADO等同于RDO。
OLE DB是應(yīng)用程序與數(shù)據(jù)源交互的一種基本技術(shù)。
這相當(dāng)復(fù)雜,確實(shí)也只有C和C++程序員能夠使用。正如ADO的名字所暗示的,它是易于訪問(wèn)OLE DB功能的ActiveX對(duì)象。
你或許發(fā)現(xiàn)術(shù)語(yǔ)ActiveX與COM對(duì)象經(jīng)常混用。對(duì)于ASP程序員來(lái)說(shuō)它們并沒(méi)有本質(zhì)上的區(qū)別,因?yàn)閮烧叨蓟贑OM系統(tǒng)結(jié)構(gòu),只不過(guò)ActiveX是組件的一個(gè)跨平臺(tái)標(biāo)準(zhǔn),而COM是Windows專有的。
雖然微軟已經(jīng)引入了一種新的存取數(shù)據(jù)的技術(shù),但并沒(méi)有立即取消舊的技術(shù),ODBC工作起來(lái)仍然很有效,并同OLE DB和ADO緊密地一起工作著。事實(shí)上,ODBC并不只是微軟的產(chǎn)品,也受到國(guó)際組件的控制。并且由于廣泛的使用,ODBC也不會(huì)突然消亡。隱藏在OLE DB背后的思想不是摒棄現(xiàn)有的技術(shù),而是不斷地改進(jìn)它們。
8.1.1 OLE DB和ADO的體系結(jié)構(gòu)
前面已經(jīng)給出了OLE DB與ADO在一些主要方面的簡(jiǎn)要解釋。圖8-1顯示了這兩項(xiàng)技術(shù)與應(yīng)用程序和數(shù)據(jù)存儲(chǔ)相互關(guān)系:
圖8-1 OLE DB、ADO與應(yīng)用程序和數(shù)據(jù)存儲(chǔ)的關(guān)系
從圖8-1中可以看出整體思路。圖的頂端是應(yīng)用程序(Web或常規(guī)的應(yīng)用程序,這是無(wú)關(guān)緊要的),下面是提供對(duì)數(shù)據(jù)的訪問(wèn)的ADO和/或OLE DB。ADO和OLE DB兩者兼有是因?yàn)镺LE DB是一項(xiàng)基本技術(shù)。然而,OLE DB并不適用于所有語(yǔ)言,所以ADO位于OLE DB的上層,為那些不能直接訪問(wèn)OLE DB的語(yǔ)言(如Visual Basic和腳本語(yǔ)言)提供編程接口。ADO提供了比OLE DB更容易的編程接口,因此即使那些可以直接使用OLE DB的編程語(yǔ)言,如C++或Java,也可使用ADO以簡(jiǎn)化對(duì)數(shù)據(jù)的訪問(wèn)。
圖8-1顯示的是微軟的編程語(yǔ)言,而ADO是一個(gè)COM組件,因此可用于任何與COM兼容的編程語(yǔ)言,比如Delphi或支持Active Scripting接口的腳本語(yǔ)言。所以,雖然ADO與平臺(tái)有關(guān),但與開發(fā)的語(yǔ)言是無(wú)關(guān)的。當(dāng)然,對(duì)于ASP主要使用VBScript和JScript,在組件中使用ADO時(shí),有一些Visual Basic代碼。
現(xiàn)在知道了OLE DB和ADO允許訪問(wèn)數(shù)據(jù),可是為什么需要它們?老方法出問(wèn)題了嗎?這里有兩個(gè)主要原因:
首先,OLE DB和ADO是用來(lái)訪問(wèn)數(shù)據(jù)存儲(chǔ)的。注意這里指“數(shù)據(jù)存儲(chǔ)”而不是“數(shù)據(jù)庫(kù)”。盡管數(shù)據(jù)庫(kù)仍舊是數(shù)據(jù)存儲(chǔ)最為廣泛的形式,但并不一定含有全部的數(shù)據(jù)。一些消息系統(tǒng),如Microsoft Exchange Server,也普遍地用于存儲(chǔ)數(shù)據(jù)。目錄服務(wù)(Directory Service)正開始在初露端倪,它們包含著有關(guān)用戶、機(jī)器等的數(shù)據(jù);Web服務(wù)器中存有大量的信息??梢岳^續(xù)羅列下去,很明顯需要一種能訪問(wèn)所有這些不同類型數(shù)據(jù)的方法。
其次,源于Internet應(yīng)用程序的興起與Web的狀態(tài)本質(zhì)。過(guò)去的訪問(wèn)數(shù)據(jù)的方法主要考慮與數(shù)據(jù)存儲(chǔ)保持永久連接的情況下處理數(shù)據(jù)。而OLE DB和ADO正是為解決這個(gè)問(wèn)題而設(shè)計(jì)的,提供斷開連接的記錄集,我們將會(huì)在后面看到有關(guān)這方面的內(nèi)容。
8.1.2 消費(fèi)者與提供者
ADO系統(tǒng)結(jié)構(gòu)圖展示了ADO是如何在應(yīng)用程序和真實(shí)數(shù)據(jù)存儲(chǔ)之間發(fā)揮作用的。在微軟的文獻(xiàn)中,會(huì)看到兩個(gè)易懂的術(shù)語(yǔ):消費(fèi)者(Consumer)和提供者(Provider),但搞清它們的確切定義至關(guān)重要。
提供者是提供數(shù)據(jù)的物體,消費(fèi)者是使用(消耗)這些數(shù)據(jù)的物體。
在編程中,經(jīng)常會(huì)發(fā)現(xiàn)應(yīng)用程序是數(shù)據(jù)的消費(fèi)者。但提供者呢?一般是數(shù)據(jù)存儲(chǔ),并且由于OLE DB被設(shè)計(jì)成用于與不同的數(shù)據(jù)存儲(chǔ)對(duì)話,因此對(duì)于每一個(gè)獨(dú)特類型的數(shù)據(jù)存儲(chǔ)都有一個(gè)OLE DB提供者。
這種單獨(dú)提供者的思想并不新,但使編程變得容易了。編寫程序與ADO或OLE DB對(duì)話,OLE DB再與提供者對(duì)話。這意味著只需學(xué)會(huì)一套訪問(wèn)數(shù)據(jù)的方法,無(wú)論數(shù)據(jù)如何存儲(chǔ),在某些情況下確實(shí)可以完全不改變?nèi)魏未a而只更換提供者。這就是ADO和OLE DB真正優(yōu)越的地方,為數(shù)據(jù)存儲(chǔ)提供了一套常用的編程接口。
要連接到數(shù)據(jù)存儲(chǔ),必須使用OLE DB提供者。提供給ADO 2.5的初始設(shè)置為:
· Jet OLE DB 4.0:用于微軟Access數(shù)據(jù)庫(kù)。
· DTS Packages:用于SQL Server的數(shù)據(jù)轉(zhuǎn)換服務(wù)(Data Transformation Services)。
· Internet Publishing:用于訪問(wèn)Web服務(wù)器。
· Indexing Services:用于索引目錄(Index Catalogs)。
· Site Server Search:用于站點(diǎn)服務(wù)器查找目錄。
· ODBC Drivers:用于ODBC數(shù)據(jù)源。
· OLAP Services:用于微軟OLAP服務(wù)器。
· Oracle:用于Oracle數(shù)據(jù)庫(kù)。
· SQL Server:用于微軟SQL Server數(shù)據(jù)庫(kù)。
· Simple Provider:用于簡(jiǎn)單的文本文件。
· MSDataShape:用于層次數(shù)據(jù)。
· Microsoft Directory Services:用于Windows 2000的目錄服務(wù)。
· DTS Flat File:用于SQL Server的數(shù)據(jù)轉(zhuǎn)換服務(wù)的平面文件管理。
這只是微軟提供的初始列表,并取決于安裝在服務(wù)器上的服務(wù)及軟件。以O(shè)racle數(shù)據(jù)提供者為例,要求在客戶機(jī)上安裝Oracle的客戶端軟件。
可以從別的制造商那里獲得OLE DB提供者,用于其他數(shù)據(jù)存儲(chǔ)。甚至還可以編寫自己的提供者。在第11章,將演示如何編寫簡(jiǎn)單的OLE DB提供者。
要想知道系統(tǒng)安裝了哪些提供者,可以使用Data Link properties對(duì)話框。在本章后面,將介紹如何使用它。
8.1.3 提供者和驅(qū)動(dòng)程序
值得注意的是,OLE DB對(duì)ODBC的兼容性,允許OLE DB訪問(wèn)現(xiàn)有的ODBC數(shù)據(jù)源。其優(yōu)點(diǎn)很明顯,由于ODBC相對(duì)OLE DB來(lái)說(shuō)使用得更為普遍,因此可以獲得的ODBC驅(qū)動(dòng)程序相應(yīng)地要比OLE DB的要多。這樣不一定要得到OLE DB的驅(qū)動(dòng)程序,就可以立即訪問(wèn)原有的數(shù)據(jù)系統(tǒng)。
避免混淆提供者與驅(qū)動(dòng)程序是重要的,圖8-2明確了它們之間的區(qū)別:
圖8-2 提供者與驅(qū)動(dòng)程序之間的區(qū)別
提供者位于OLE DB層,而驅(qū)動(dòng)程序位于ODBC層。如果想使用一個(gè)ODBC數(shù)據(jù)源,需要使用針對(duì)ODBC的OLE DB提供者,它會(huì)接著使用相應(yīng)的ODBC驅(qū)動(dòng)程序。如果不需要使用ODBC數(shù)據(jù)源,那么可以使用相應(yīng)的OLE DB提供者,這些通常稱為本地提供者(native provider)。
可以清楚地看出使用ODBC提供者意味著需要一個(gè)額外的層。因此,當(dāng)訪問(wèn)相同的數(shù)據(jù)時(shí),針對(duì)ODBC的OLE DB提供者可能會(huì)比本地的OLE DB提供者的速度慢一些。
8.2 ADO 2.5對(duì)象模型
雖然在ADO 2.5對(duì)象模型中出現(xiàn)了兩個(gè)新對(duì)象,但與以前的版本基本上是類似的。圖8-3顯示了這些對(duì)象以及每個(gè)對(duì)象之間的關(guān)系:
圖8-3 對(duì)象之間的相互關(guān)系
如果以前使用過(guò)ADO,你會(huì)發(fā)現(xiàn)在這個(gè)新版本中出現(xiàn)了兩個(gè)新對(duì)象:Stream和Record對(duì)象。在第11、12章將詳細(xì)介紹它們。
Properties集合已經(jīng)被有意地排除在圖8-3外,這樣你對(duì)幾個(gè)主要對(duì)象之間的交互關(guān)系就一目了然了。在本章的后面,有顯示Properties集合的簡(jiǎn)化對(duì)象模型。
讓我們更詳細(xì)地考察這幾個(gè)對(duì)象。
8.2.1 Connection對(duì)象
Connection對(duì)象是使我們能與數(shù)據(jù)存儲(chǔ)相連的對(duì)象。只有Connection對(duì)象才能指定希望使用的OLE DB提供者、連接到數(shù)據(jù)存儲(chǔ)的安全細(xì)節(jié)以及其他任何連接到數(shù)據(jù)存儲(chǔ)特有的細(xì)節(jié)。
應(yīng)用注意的是,不必顯式創(chuàng)建一個(gè)Connection對(duì)象以連接到數(shù)據(jù)存儲(chǔ)。盡管確實(shí)需要指定連接細(xì)節(jié),但沒(méi)有Connection對(duì)象,一樣可以創(chuàng)建Command、Recordset和Record對(duì)象。如果不創(chuàng)建自己的Connection對(duì)象,ADO將會(huì)隱含地為你創(chuàng)建一個(gè)Connection對(duì)象。如果要對(duì)提供者運(yùn)行多條命令,應(yīng)該顯式地創(chuàng)建一個(gè)Connection對(duì)象,這比每運(yùn)行一條命令就創(chuàng)建一個(gè)連接更有效。
除了為數(shù)據(jù)存儲(chǔ)提供連接以外,Connection對(duì)象允許針對(duì)數(shù)據(jù)存儲(chǔ)執(zhí)行命令操作。這些命令可以是結(jié)構(gòu)化的或存儲(chǔ)的命令(例如,SQL命令或一個(gè)存儲(chǔ)過(guò)程),并且可以有選擇地從數(shù)據(jù)存儲(chǔ)中返回一些數(shù)據(jù)。
8.2.2 Command對(duì)象
Command對(duì)象是對(duì)數(shù)據(jù)存儲(chǔ)執(zhí)行命令的對(duì)象??吹竭@里讀者可能會(huì)產(chǎn)生疑問(wèn),Connection對(duì)象不也能這樣做嗎?是的,但是Connection對(duì)象在處理命令的功能上受到一定的限制,而Command對(duì)象是特別為處理命令的各方面問(wèn)題而創(chuàng)建的。實(shí)際上,當(dāng)從Connection對(duì)象中運(yùn)行一條命令時(shí),已經(jīng)隱含地創(chuàng)建一個(gè)Command對(duì)象。
有時(shí)其他對(duì)象允許向命令傳入?yún)?shù),但在Connection對(duì)象中不能指定參數(shù)的任何細(xì)節(jié)。使用Command對(duì)象允許指定參數(shù)(以及輸出參數(shù)和命令執(zhí)行后的返回值)的精確細(xì)節(jié)(比如,數(shù)據(jù)類型和長(zhǎng)度)。
因此,除了執(zhí)行命令和得到一系列返回記錄,也可能得到一些由命令提供的附加信息。
對(duì)于那些不返回任何記錄的命令,如插入新數(shù)據(jù)或更新數(shù)據(jù)的SQL查詢,Command對(duì)象也是有用的。
8.2.3 Recordset對(duì)象
Recordset對(duì)象是ADO中使用最為普遍的對(duì)象,因?yàn)樗袕臄?shù)據(jù)存儲(chǔ)中提取的數(shù)據(jù)集。我們經(jīng)常運(yùn)行不返回?cái)?shù)據(jù)的命令,比如那些增加或更新數(shù)據(jù)的命令,但在大多數(shù)情況下很有可能會(huì)取得一系列記錄。
Recordset對(duì)象是擁有這些記錄的對(duì)象??梢愿模ㄔ黾?、更新和刪除)記錄集中的記錄,上下移動(dòng)記錄,過(guò)濾記錄并只顯示部分內(nèi)容等等。Recordset對(duì)象也包含F(xiàn)ields集合,F(xiàn)ields集合中有記錄集中每一個(gè)字段(列)的Filed對(duì)象。
無(wú)論是在ASP頁(yè)面中處理數(shù)據(jù),還是利用遠(yuǎn)程數(shù)據(jù)服務(wù)(RDS)遠(yuǎn)程使用數(shù)據(jù),Recordset對(duì)象是必須處理的對(duì)象。
8.2.4 Record對(duì)象
ADO 2.5以前的版本在處理結(jié)構(gòu)化數(shù)據(jù)上是很有效的,比如從數(shù)據(jù)庫(kù)中取出記錄集,但無(wú)法處理每一行的列(也就是列數(shù)和數(shù)據(jù)類型)可能不同的數(shù)據(jù)。對(duì)于SQL數(shù)據(jù)這不是一個(gè)問(wèn)題,但對(duì)于文件和郵件系統(tǒng),Web服務(wù)器和別的諸如此類的數(shù)據(jù)存儲(chǔ)會(huì)如何呢?我們把這些數(shù)據(jù)看作是半結(jié)構(gòu)化的數(shù)據(jù),與記錄集相比結(jié)構(gòu)性較差,但與那些常用來(lái)代表文本或圖像的二進(jìn)制數(shù)據(jù)相比更具有結(jié)構(gòu)性。
通常,半結(jié)構(gòu)化數(shù)據(jù)的存儲(chǔ)采用樹狀結(jié)構(gòu)來(lái)組織,有節(jié)點(diǎn)、子節(jié)點(diǎn)和文件。例如,設(shè)想一個(gè)有文件夾、子文件夾和文件的Web站點(diǎn)。圖8-4所示的屏幕圖顯示了一臺(tái)機(jī)器的Web站點(diǎn),特別是還有一個(gè)名為public的虛擬目錄:
圖8-4 顯示了一臺(tái)機(jī)器的Web站點(diǎn)的界面
如果一定要在ADO中進(jìn)行建模,會(huì)覺(jué)得這非常適合記錄集,可能是嵌套的記錄集。然而注意高亮度顯示的目錄,該目錄含有不同類型的文件,里面有幾個(gè)目錄、兩個(gè)ASP文件、一個(gè)文本文件和一個(gè)WORD文檔。你會(huì)很容易地將其映射到一個(gè)擁有名稱、類型、上次存取時(shí)間等字段的記錄集,遺憾的是并不是這樣簡(jiǎn)單。對(duì)于訪問(wèn)權(quán)限而言,在文件和目錄之間就有區(qū)別。對(duì)于目錄,需要的是能訪問(wèn)目錄下的文件;而對(duì)于文件,卻可能是需要訪問(wèn)其內(nèi)容。
由于其復(fù)雜性,引入了Record對(duì)象。在上面的情況下,存在有一些相同屬性的條目的一個(gè)集合,但是每個(gè)條目也有獨(dú)特的屬性,因此需要使用別的方法去處理這些數(shù)據(jù)。把一個(gè)集合映射到一個(gè)記錄集,一個(gè)單獨(dú)的文件映射成一條記錄,相應(yīng)的文件屬性就映射成Fields集合。
這意味著有了一個(gè)含有六行記錄的記錄集。訪問(wèn)記錄集中單獨(dú)的一行就會(huì)得到該文件的屬性(字段),但是提供給我們的僅僅是屬性,為了訪問(wèn)文件或目錄的內(nèi)容,需要使用Record對(duì)象,該對(duì)象包含文件或目錄的獨(dú)特屬性。習(xí)慣于這個(gè)概念有一定的困難,但不必?fù)?dān)心,在第11、12章你會(huì)看到更多有關(guān)Record對(duì)象的例子。 Windows 2000初始版本發(fā)布以來(lái),只有用于Internet發(fā)布的OLE DB提供者使用Record對(duì)象。一旦微軟Exchange 6.0發(fā)布,將成為以類似方法利用記錄集和記錄提供對(duì)Exchange信息庫(kù)訪問(wèn)的OLE DB提供者。