ADO(ActiveXDataObjects)是Microsoft提供和建議使用的新型的數(shù)據(jù)訪問(wèn)接口,具體實(shí)現(xiàn)為Automation。這樣,程序員可以在各種支持Automation的開(kāi)發(fā)環(huán)境下方便地訪問(wèn)ADO對(duì)象,如VisualBasic、VisualC++、VisualJ++及Delphi等。ADO被實(shí)現(xiàn)為OLEDB之上的一個(gè)薄層,這使得ADO可以有更快的訪問(wèn)速度,更易使用,同時(shí)更節(jié)省資源。值得注意的是,對(duì)于VisualStudio6.0的用戶(hù)而言,現(xiàn)在提供的ADO2.0要比VisualStudio5.0時(shí)代的ADO1.5更加完整。這意味著程序員可以更為廣泛地使用ADO接口,甚至在所有的基于Windows平臺(tái)的數(shù)據(jù)訪問(wèn)中使用它。比如對(duì)RDS(前身是ADC)的支持,可以方便的構(gòu)建高效的Web應(yīng)用。
一、對(duì)ADO對(duì)象的主要操作 對(duì)ADO對(duì)象的主要操作,同DAO、RDO庫(kù)的實(shí)現(xiàn)基本相同。主要包括6個(gè)方面:
1.連接到數(shù)據(jù)源。這是可選的、通常涉及ADO的Connection對(duì)象。
2.向數(shù)據(jù)源提交命令。通常涉及ADO的Command對(duì)象。在查詢(xún)中可以與參數(shù)對(duì)象(Parameter)協(xié)同使用。
3.執(zhí)行命令,比如一個(gè)SELECT腳本。
4.如果提交的命令有結(jié)果返回,可以通過(guò)ADO的Recordset對(duì)象對(duì)結(jié)果進(jìn)行操作,數(shù)據(jù)存儲(chǔ)在緩存中。
5.如果合適,可將緩存中被修改的數(shù)據(jù)更新到物理的存儲(chǔ)上。
6.提供錯(cuò)誤檢測(cè)。通常涉及ADO的Error對(duì)象。
以程序員的視角來(lái)看,ADO、DAO和RDO三者的對(duì)象名稱(chēng)不很相同。但使用ADO對(duì)象要比DAO和RDO簡(jiǎn)單得多。最主要的一點(diǎn)在于,程序員不用像在使用DAO和RDO那樣要從對(duì)象模型的頂層開(kāi)始一步步的創(chuàng)建子對(duì)象。因此,ADO提供了一種更靈活的編程方式。
二、ADO中主要對(duì)象的功能 Connection對(duì)象,表示了一個(gè)到數(shù)據(jù)源的會(huì)話(huà)。使用Connection對(duì)象的成員,可以使用相應(yīng)的屬性打開(kāi)到數(shù)據(jù)源的連接,設(shè)置游標(biāo)的位置,設(shè)置默認(rèn)的當(dāng)前數(shù)據(jù)庫(kù),設(shè)置將使用的OLEDBProvider,直接提交SQL腳本等。值得注意的是,在提交SQL腳本的任務(wù)時(shí),不用創(chuàng)建一個(gè)Command對(duì)象,就可完成查詢(xún)。另外,對(duì)Connection對(duì)象的創(chuàng)建是同其他對(duì)象無(wú)關(guān)的。Command對(duì)象,可被用于查詢(xún)數(shù)據(jù)庫(kù)并返回結(jié)果在Recordset對(duì)象中。也可以進(jìn)行批操作和操縱數(shù)據(jù)庫(kù)的結(jié)構(gòu),當(dāng)然,這需要使用的OLEDBProvider提供相應(yīng)的支持。此外,可以將一個(gè)激活的Connection對(duì)象綁定到Command對(duì)象的ActiveConnection屬性,這使得多個(gè)Command對(duì)象實(shí)例可以共用一個(gè)Connection對(duì)象。
Recordset對(duì)象,用來(lái)封裝查詢(xún)的結(jié)果,可稱(chēng)為結(jié)果集。
Field對(duì)象,用來(lái)表達(dá)一行結(jié)果中各子段的類(lèi)型和值。
Error對(duì)象,用來(lái)檢測(cè)和判斷在數(shù)據(jù)庫(kù)操作中出現(xiàn)的錯(cuò)誤,比如連接失敗。 在ADO中,許多對(duì)象名后多了一個(gè)"s",比如Error->Errors,F(xiàn)ield->Fields等等。添加"s"意味著是相應(yīng)對(duì)象的Collection(集合)對(duì)象,比如Errors是Error對(duì)象的Collection對(duì)象。Collection有點(diǎn)像數(shù)組(Array),但不同的是,Collection可以以不同類(lèi)型的數(shù)據(jù)或?qū)ο笞鳛樽约旱脑?,而?shù)組中的各元素通常都是相同類(lèi)型的。所以,在看到一個(gè)對(duì)象名最后是"s",通常表明這是一個(gè)Collection對(duì)象,比如Errors中的各元素是由Error對(duì)象的實(shí)例組成的。
三、簡(jiǎn)單的例子 現(xiàn)在,我們?cè)诮?jīng)過(guò)了前面的鋪墊后,終于可以進(jìn)入寫(xiě)代碼的過(guò)程了。下面是一系列在VisualBasic中編寫(xiě)的代碼片段,其中對(duì)ADO的操縱完全用代碼來(lái)實(shí)現(xiàn)。在開(kāi)始前,請(qǐng)不熟悉ActiveXAutomation的讀者牢記,我們正在使用的,是被實(shí)現(xiàn)為ActiveXAutomation的ADO組件。1.打開(kāi)Connect.ion對(duì)象
打開(kāi)一個(gè)到數(shù)據(jù)源的連接,即Connection對(duì)象的VB代碼如下:
Dim cn As ADODB.Connection
’聲明ADODB.Connection對(duì)象變量
Dim strCN As String
’聲明存放連接串的字符串變量
Set cn= New Connection
’實(shí)例化Connection對(duì)象
’生成連接串(ConnectionString)
strCN="Provider=Microsoft.Jet.Oledb.3.51;
UserID=Admin;"&_
"DataSource=D:\MicrosoftVisual
Studio\VB98\Nwind.mdb;"
cn.Open strCN ’調(diào)用Connection對(duì)象的方法Open連接數(shù)據(jù)源
以上代碼在訪問(wèn)ADO對(duì)象時(shí),使用了前綁定(Early-bind),實(shí)現(xiàn)前綁定需要從VisualBasic的Project菜單下選擇Reference菜單項(xiàng),并選擇MicrosoftActiveXDataObjects2.0Library。在程序中聲明的strCN變量中,連接串屬性Provider標(biāo)識(shí)了OLEDBProvider為OLEDBProviderforMicrosoftJet,因?yàn)槲覀冊(cè)L問(wèn)的是MicrosoftAccess數(shù)據(jù)文件,使用MicrosoftJetEngine可以獲得比ODBC更好的性能。在試驗(yàn)以上代碼時(shí)有兩個(gè)地方要注意。首先,要根據(jù)系統(tǒng)安裝的OLEDBProviderforMicrosoftJet服務(wù)選擇相應(yīng)版本,可能是3.51,也可能是4.0。在本例中使用的是3.51版本。如果使用4.0版本,首先需要將Provider屬性改為"Microsoft.Jet.Oledb.4.0";其次,DataSource屬性標(biāo)識(shí)了所要訪問(wèn)的數(shù)據(jù)文件的路徑,要根據(jù)自己的安裝情況作出適當(dāng)?shù)恼{(diào)整。文件Nwind.mdb通常被VisualStudio默認(rèn)安裝,一般放在Visual Basic的工作目錄下。
除了OLEDB Provider for MicrosoftJet以外,Visual Studio6.0還提供了以下的OLEDBProvider,如下所示。
OLEDB Provider類(lèi)型 | 數(shù)據(jù)源類(lèi)型 |
Microsoft OLEDB Provider for ODBC | databases |
Microsoft OLEDB Provider for Microsoft Index Server | Microsoft(r) Index Server |
Microsoft OLEDB Provider for Microsoft Active Directory Service | Microsoft(r) Active Directory Service |
Microsoft OLEDB Provider for SQLServer Microsoft(r) SQLServer | Microsoft OLEDB Provider for Oracle |
Oracle | databases |
這意味著使用ADO接口可以方便地訪問(wèn)以上的各種數(shù)據(jù)源,要做的就是選擇適當(dāng)?shù)腛LEDB Provider。除了使用Connection對(duì)象的Open方法以外,還可通過(guò)Recordset對(duì)象的Open方法快捷地創(chuàng)建到數(shù)據(jù)源的連接。這充分體現(xiàn)了ADO的靈活性。
2.創(chuàng)建Command對(duì)象
Dim cmd As ADODB.Command
Set cmd=New Command’實(shí)例化Command對(duì)象
3.執(zhí)行查詢(xún)
以Command對(duì)象為例。
Dim rs As New ADODB.Recordset
Set cmd.ActiveConnection=cn’綁定激活的Connection對(duì)象實(shí)例
cmd.CommandText="SELECT*from Customers"’生成SQL腳本
Set rs=cmd.Execute’執(zhí)行查詢(xún)
上述的代碼僅僅是一種查詢(xún)途徑,此外,ADO的Connection對(duì)象的Execute方法和Recordset對(duì)象的Open方法也提供了查詢(xún)能力。返回的結(jié)果可以被保存在一個(gè)Recordset對(duì)象實(shí)例中以便后續(xù)的數(shù)據(jù)處理和操縱。例如:
Dim rs As NewADODB.Recordset
rs.Open cmd,cn,adOpenDymanic,adLockBatchOptimistic
另外在SQL腳本的生成方式上,通??梢越柚鶳arameters/Parameter對(duì)象來(lái)完成。
4.顯示和操縱數(shù)據(jù)
查詢(xún)結(jié)果由Recordset對(duì)象封裝。對(duì)數(shù)據(jù)的操縱可以通過(guò)Recordset對(duì)象提供的成員(屬性和方法)來(lái)完成。
rs.MoveFirst
Do While Not rs.EOF’判斷EOF標(biāo)記屬性(Endoffile)
Debug.Print rs!CustomerID & vbTab & rs!CompanyName & _
vbTab & rs!ContactName & vbTab & rs!ContactTitle
rs.MoveNext’將游標(biāo)指針移到下一條記錄
Loop
上述代碼將Recordset中的各行記錄打印在Visual Basic的Immediate Window中。為了看到打印的結(jié)果,可以在上述代碼之后,增加一條Stop語(yǔ)句,以便進(jìn)入Debug狀態(tài)。
5.更新記錄
使用Recordset對(duì)象來(lái)完成Update操作。
rs.Close’關(guān)閉之前建立的結(jié)果集
’打開(kāi)新的結(jié)果集,具有寫(xiě)操作權(quán)限
rs.Open"Customers",cn,adOpenDynamic,adLockOptimistic,adCmdTable
rs.MoveFirst’雖無(wú)必要,但可能是一個(gè)良好的習(xí)慣
rs!CompanyName="Microsoft"’對(duì)相應(yīng)字段賦予新值
rs.Update’在物理存儲(chǔ)上生效
除了Update以外,寫(xiě)操作還包括AddNew(添加一條新記錄)和Delete(刪除一條新記錄)。另外,Recordset支持批處理,但這些特征需要由低層的OLEDBProvider支持。當(dāng)寫(xiě)操作出現(xiàn)錯(cuò)誤時(shí),可根據(jù)錯(cuò)誤描述(訪問(wèn)ADO的Error或VisualBasic的Err對(duì)象)來(lái)判斷原因。另一個(gè)需要注意的是,當(dāng)使用Recordset對(duì)象完成寫(xiě)操作時(shí),需要預(yù)先指定Recordset對(duì)象實(shí)例非只讀。
6.收尾工作
在這個(gè)階段應(yīng)該顯式的釋放相應(yīng)的資源,如果不做的話(huà),通常VisualBasic會(huì)自動(dòng)釋放和回收資源。但對(duì)于一個(gè)有良好編程習(xí)慣的程序員來(lái)說(shuō),應(yīng)該主動(dòng)地做收尾工作,就像下面的代碼一樣。
rs.Close
Set rs=Nothing
Set cmd=Nothing
cn.Close
Set cn=Nothing