微軟公司的ADO (ActiveX Data Objects) 是一個用於存取數據源的COM組件。它提供了編程語言和統一數據訪問方式OLE DB的一個中間層。允許開發人員編寫訪問數據的代碼而不用關心數據庫是如何實現的,而只用關心到數據庫的連接。訪問數據庫的時候,關於SQL的知識不是必要的,但是特定數據庫支持的SQL命令仍可以通過ADO中的命令對象來執行。ADO被設計來繼承微軟早期的數據訪問對象層,包括RDO (Remote Data Objects) 和DAO(Data Access Objects)。ADO在1996年冬被發布。
ADO 對象總結:
連接,代表到數據庫的連接
記錄集,代表數據庫記錄的一個集合
命令,代表一個SQL命令
記錄,代表數據的一個集合
流,代表數據的順序集合
錯誤,代表數據庫訪問中產生的意外
字段,代表一個數據庫字段
參數,代表一個SQL參數
ADO組件的使用需要利用支持COM的高級語言,例如ASP中的VBScript或者Visual Basic,甚至Delphi,
微軟
的競爭對手Borland的一個產品,現在也支持使用ADO來訪問數據庫。
在新的編程框架.NET Framework中, 微軟也提供了一個面向Internet的版本的ADO,稱為ADO.N ET。其對象模型和傳統ADO差別很大。 ADO是一種
面向對象
的編程接口,微軟介紹說,與其同IBM和Oracle提倡的那樣,創建一個統一數據庫,不如提供一個能夠訪問不同數據庫的統一接口,這樣會更加實用一些。為實現這一目標,微軟在數據庫和微軟的OLE DB中提供了一種“橋”程序,這種程序能夠提供對數據庫的連接。 開發人員在使用ADO時,其實就是在使用OLE DB,不過OLE DB更加接近底層。ADO的一項屬性遠程數據服務,支持“數據倉庫”ActiveX 組件以及高效的
客戶端
緩存。作為ActiveX的一部分,ADO也是
COM組件
的一部分。ADO是由早期的微軟數據接口??遠程
數據對象
RDO演化而來的。RDO同微軟的ODBC一同連接關系數據庫,不過不能連接非關系數據庫。
ADO向我們提供了一個熟悉的,高層的對OLE DB的Automation封裝接口。對那些熟悉RDO的
程序員
來說,你可以把OLE DB比作是
ODBC驅動程序
。如同RDO對象是ODBC驅動程序接口一樣,ADO對象是OLE DB的接口;如同不同的
數據庫系統
需要它們自己的ODBC驅動程序一樣,不同的數據源要求它們自己的OLE DB提供者(OLE DB provider)。目前,雖然OLE DB提供者比較少,但微軟正積極推廣該技術,並打算用OLE DB取代ODBC。
ADO向VB程序員提供了很多好處。包括易於使用,熟悉的
界面
,高速度以及較低的內存占用(已實現ADO2.0的Msado15.dll需要占用342K內存,比RDO的Msrdo20.dll的368K略小,大約是DAO3.5的Dao350.dll所占內存的60%)。同傳統的數據對象層次(DAO和RDO)不同,ADO可以獨立創建。因此你可以只創建一個"Connection"對象,但是可以有多個,獨立的"Recordset"對象來使用它。ADO針對客戶/服務器以及WEB
應用程序
作了優化。
ADO (ActiveX Data Objects,
ActiveX數據對象
)是Microsoft提出的
應用程序接口
(API)用以實現訪問關系或非關系數據庫中的數據。例如,如果您希望編寫應用程序從DB2或
Oracle數據庫
中向網頁提供數據,可以將ADO程序包括在作為活動服務器頁(ASP)的
HTML文件
中。當用戶從網站請求網頁時,返回的網頁也包括了數據中的相應數據,這些是由於使用了ADO代碼的結果。
象Microsoft的其它系統接口一樣,ADO是面向對象的。它是Microsoft全局數據訪問(UDA)的一部分,Microsoft認為與其自己創建一個數據,不如利用UDA訪問已有的數據庫。為達到這一目的,Microsoft和其它數據庫公司在它們的數據庫和Microsoft的OLE數據庫之間提供了一個“橋”程序,OLE數據庫已經在使用ADO技術。ADO的一個特征(稱為遠程數據服務)支持網頁中的數據相關的
ActiveX控件
和有效的客戶端緩沖。作為ActiveX的一部分,ADO也是Microsoft的組件對象
模式
(COM)的一部分,它的面向組件的框架用以將程序組裝在一起。
ADO從原來的Microsoft數據接口遠程數據對象(RDO)而來。RDO與ODBC一起工作訪問關系數據庫,但不能訪問如ISAM和VSAM的非關系數據庫。
ADO 是對當前微軟所支持的數據庫進行操作的最有效和最簡單直接的方法,它是一種功能強大的數據訪問編程模式,從而使得大部分數據源可編程的屬性得以直接擴展到你的Active Server 頁面上。可以使用ADO 去編寫緊湊簡明的
腳本
以便連接到 Open Database Connectivity (ODBC) 兼容的數據庫和 OLE DB 兼容的數據源,這樣 ASP 程序員就可以訪問任何與 ODBC 兼容的數據庫,包括 MS SQL SERVER、Access、 Oracle 等等。
比如,如果網站開發人員需要讓用戶通過訪問網頁來獲得存在於IBM DB2或者Oracle數據庫中的數據,那么就可以在ASP頁面中包含ADO程序,用來連接數據庫。於是,當用戶在網站上瀏覽網頁時,返回的網頁將會包含從數據庫中獲取的數據。而這些數據都是由ADO代碼做到的。
目前ADO1.5版已經可以從微軟網站免費下載。到目前為止,微軟網站仍是你獲取有關ADO最新信息的最佳場所。ADO1.5是作為OLE DB SDK的一部分提供的。
在下載之前請先確認OLE DB SDK提供的各項特性。下載文件大約有15M,如果完全安裝的話要占用80M的硬盤空間。如果你只對ADO感興趣,就選擇最小安裝,這樣只會占用你15M的硬盤空間。
在這里你可以找到許多關於ADO的示例代碼和文章,尤其是在"Workshop"系列的文章中。你也可以從本站下載ADO2.5的幫助文件。
盡管OLE DB SDK提供自己的ADO幫助文件,你會發現ADO1.0的幫助文件更易於使用。同時它還向你提供ADO對象模型的圖示
ADO是如何組織起來的?
以前的對象模型,如DAO和RDO是層次型的。也就是說一個較低的數據對象如Recordset是幾個較高層次的對象,如Environment和QueryDef,的
子對象
。在創建一個QueryDef對象的實例之前,你不能創建DAO
ADO 2.0特點
ADO 對象編程模型
ADO使用方法
最重要的三個ADO對象是Connection, Recordset和Command. 本文將主要介紹Connection和Recordset這兩個對象。每個Connection的屬性定義了與數據源的連接。Recordset對象接收來自數據源的數據。Recordset可以與Connection一起起使用,先建立一個連接,然后獲取數據。盡管如此,Recordset也可以被單獨創建,其Connection參數可以在Open屬性定義。
對於ADO1.5以前包括1.5的版本來說,從功能的角度來看RDO和ADO不是完全相等的.等同就意味着你可以通過這兩種方法解決同樣的問題;它不是指存在
重命名
的或者優化的功能相同的對象.因此,移植到ADO 不是一個簡單的事情.從另一方面來說,一旦你熟練掌握了RDO或ADO技術的話,學習ADO是件相當容易的事情.
ADO 2.0的新特性包括事件處理,記錄集的延續,分層目錄結構指針和數據成形,分布式事務處理,多維數據,遠程數據服務(RDS),以及對C++和Java的支持的增強.在鑽研一些Visual Basic代碼的時候將會見到所有的這些特性.當使用
Visual J++
時,我將舉例說明新的Windows Foundation Classes(WFC)是如何支持ADO的.ADO的最讓人激動的是在Visual Studio 6.0中的任何開發工具中你都可以找到對它的充分的支持.
連接數據源 (Connection),可選擇開始事務。
可選擇創建表示 SQL 命令的對象 (Command)。
執行命令(Command、Connection 或 Recordset)。
如果命令以行返回,將行存儲在存儲對象中 (Recordset)。
可選擇創建存儲對象的視圖以便進行排序、篩選和定位數據 (Recordset)。
編輯數據。可以添加、刪除或更改行、列 (Recordset)。
在適當情況下,可以使用存儲對象中的變更對數據源進行更新 (Recordset)。
在使用事務之后,可以接受或拒絕在事務中所做的更改。結束事務 (Connection)。
一旦安裝了ADO,在VB的工程->引用對話框中你就可以看到象下圖所示的東西了:
選擇ActiveX Data Objects 1.5 Library(ADODB).在其下的 "ADO Recordset 1.5 Library"是一個客戶端的版本(ADOR),它定義了有聚的
數據訪問對象
。ADOR 對於客戶端的數據訪問來說是足夠的了,因為你不需要
Connection對象
來建立與遠程數據源的聯系。
如果你想要訪問更多的外部數據源,你需要安裝這些外部數據源自己的OLE DB Provider,就象你需要為新的數據庫系統安裝新的ODBC驅動程序一樣。如果該外部數據源沒有自己的OLE DB Provider,你就得使用OLE DB SDK來自己為這個外部數據源創建一個OLE DB Provider了。這已不是本文討論的范圍了。
示例
下面的示例代碼以Northwinds數據庫作為遠程數據源,然后用ADO來訪問它。首先在控制面板中打開“32位數據源”,單擊“添加”按鈕。在彈出的對話框中選擇 "Microsoft Access Driver (*.mdb)" 作為數據源驅動程序。
然后按下圖所示,在對話框中填寫下面的內容
點擊(此處)折疊或打開
- Private Sub Form_Load()
- Dim cn As ADODB.Connection
- Set cn = New ADODB.Connection
- 'Set Connection properties
- cn.ConnectionString = "DSN=RDC Nwind;UID=;PWD=;"
- cn.ConnectionTimeout = 30
- cn.Open
- If cn.State = adStateOpen Then _
- MsgBox "Connection to NorthWind Successful!";
- cn.Close
- End Sub
按F5運行程序,看看,一個消息框彈出來告訴你連接成功了。請注意,這里我特別注明了是ADODB.Connection,而不是ADOR.Connection,這樣做是為了將二者區分開(如果你引用了ADODB和ADOR的話,這樣做很有必要)。連接字符串看上去同RDO的連接字符串差不多。事實上,二者確實差不多。
如果我們要訪問一個SQL server數據庫,你的Connection代碼看上去應象下面所示:
'設置連接屬性cn.Provider = "MSDASQL"
cn.ConnectionString = "driver={SQL Server};" & "server=prod1;uid=bg;pwd=;database=main"
cn.Open
"Provider"屬性指向SQL Server的OLE DB Provider.
回到我們的示例程序,讓我們創建一個Recordset對象來訪問“Orders”表,並從該表的"ShipCountry"字段中產生頭十個不重復的國家名。修改窗體Load事件中的代碼,讓它看上去象下面這樣。
點擊(此處)折疊或打開
- Private Sub Form_Load()
- Dim cn As ADODB.Connection
- Dim rs As ADODB.Recordset
- Dim sSQL As String
- Dim sOut As String
- Dim Count As Integer
- Set cn = New ADODB.Connection
- Set rs = New ADODB.Recordset
- ' Set properties of the Connection.
- cn.ConnectionString = "DSN=RDC Nwind;UID=;PWD=;"
- cn.ConnectionTimeout = 30
- cn.Open
- If cn.State = adStateOpen Then _
- MsgBox "Connection to NorthWind Successful!";
- sSQL = "SELECT DISTINCT Orders.ShipCountry FROM Orders"
- Set rs = cn.Execute(sSQL)
- 'Enumerate the recordset
- sOut = ""
- For Count = 1 To 10
- sOut = sOut & rs("ShipCountry") & vbCrLf
- rs.MoveNext
- Next Count
- MsgBox sOut, vbExclamation, "ADO Results"
- cn.Close
- End Sub
運行程序后,你會看到如下圖所示的消息框。
不幸的是,目前這個Recrodset對象是只讀的和forward cursor。如果你想要獲取更多的功能,你需要創建一個獨立的Recordset對象,該對象擁有自己的Connection屬性,就象下面的代碼所示:
點擊(此處)折疊或打開
- Private Sub Form_Load()
- Dim rs As ADODB.Recordset
- Dim sSQL As String
- Dim sOut As String
- Dim Count As Integer
- Set rs = New ADODB.Recordset
- sSQL = "SELECT DISTINCT Orders.ShipCountry FROM Orders"
- rs.Open sSQL, "DSN=RDC Nwind;UID=;PWD=;", adOpenDynamic
- 'Report Recordset Connection information
- MsgBox rs.ActiveConnection, , "Connection Info"
- 'Enumerate the recordset
- sOut = ""
- For Count = 1 To 10
- sOut = sOut & rs("ShipCountry") & vbCrLf
- rs.MoveNext
- Next Count
- MsgBox sOut, vbExclamation, "ADO Results"
- rs.Close
- End Sub
上面代碼返回的結果同前例一樣,但是本代碼中的Recordset是獨立的。這一點是DAO和RDO做不到的。Recordset對象的Open方法打開一個代表從SQL查詢返回的記錄的游標。雖然你可以用Connection對象同遠程數據源建立連接,但請記住,在這種情況下,Connection對象和Recordset對象是平行的關系。
總結
本文僅向你介紹了ADO強大的功能的冰山一角。微軟承諾,在將來ADO將會取代DAO和RDO。所以現在你應該考慮如何將你的數據訪問代碼投向ADO的懷抱。這種轉變不會很痛苦,因為ADO的語法同現有的語法差不多。也許微軟或第三方會在將來開發出轉換向導來簡化這一轉換過程。從現在起,你就應開發純ADO代碼的程序。你也可以繼續使用DAO或RDO代碼來開發你的程序,但落伍的感覺總是不好的。
ADO編程應用
ADO(ActiveX Data Objects)是基於組件的數據庫編程接口,它是一個和
編程語言
無關的COM組件系統。本文主要介紹用ADO編程所需要注意的技巧和在VC下進行ADO 編程的模式,並對C++Extensions進行了簡單的討論,希望對ADO開發人員有一定的幫助作用。因為ADO是一個和編程語言無關的COM組件系統,所以這里討論的要點適用於所有的編程語言和編程環境,比如:VB、VBScript、VC、Java等等。
實際上,這條准則不僅適用於ADO編程,也適用於其他的與COM對象相關的編程。因為如果一開始就定義變量類型,則
編譯器
在編譯的時候就可以知道變量的類型,此時編譯器實際上是采用vtable偏移的方式來得到具體的COM對象包含的方法的
地址
(這一點和 C++中虛函數的地址獲取方式類似);但如果一開始不指定變量類型的話,比如簡單地采用如下的語句:
DIM myCon as Object
或者是:
DIM myCon
這樣,編譯器在編譯的時候就不能得到變量的類型,而只能在運行的時候
動態
地得到方法的信息(通過使用接口IDispatch的Invoke方法來實現),如此為了得到方法的地址和相關的變量情況就需要在內部進行兩次調用,無疑會降低程序的運行速度。
在程序開始時就建立對字段對象的引用,可以避免在每次得到記錄后,再在Recordset::Fields中進行查找而增加系統的開銷。
例如,可以采用如下所示的代碼:
點擊(此處)折疊或打開
- Private Sub TblBrowse_Click()
- Dim fld1 As ADODB.Field
- Dim fld2 As ADODB.Field
- Dim rs As ADODB.Recordset
- set rs=g_cn.execute(...)
- 'g_cn為全局對象adodb.connection
- Set fld1 = rs.Fields(“id”) '數據表的字段
- Set fld2 = rs.Fields(“name”) ’數據表的字段
- If rs.BOF = False Then
- While rs.BOF = False
- Debug.Print fld1.Value
- Debug.Print fld2.Value
- rs.MoveNext
- Wend
- End If
- rs.Close
- End Sub
盡管采用Recordset對象來更新數據是非常方便的,但是它的開銷也大,通過數據源對象返回的查詢集不僅包含了數據,而且也包含了元數據(metadata), 在有些時候元數據可能比數據本身還要大,所以最好采用SQL語句來更新數據。還有要使用存儲過程而不是單一的SQL語句來獲取信息。因為存儲過程是在服務器端執行的,只把結果返回到客戶端,這樣一方面可以降低網絡進行數據交互的開銷,另一方面使系統更加容易維護,並且能保持數據的一致性。
在使用游標時,最好使用集合的方法對單條的SELECT語句進行操作。Recordset:: get_Collect方法和Recordset::put_Collect方法是Recordset 對象的快捷方式,可以快速地得到一個字段的值而不需要獲得關於一個字段的引用。例如,可以采用如下代碼:
點擊(此處)折疊或打開
- Sub Collect()
- Dim rs As New Recordset
- rs.ActiveConnection = “...”
- rs.Source=“一條SQL查詢語句”
- rs.Open
- Debug.Print rs.Collect(0),rs.Collect(1),rs.Collect(2)
- Debug.Print rs!au_id, rs!au_fname, rs!au_lname
- End Sub
盡管很多開發人員都習慣采用“SELECT * FROM TBL”的模式進行查詢,但是為了提高系統的效率,如果只需要其中某幾個字段的值,最好把這幾個字段直接寫出來,同時需要限定返回記錄集的范圍(通過WHERE子句進行限定)。
如果只需要按順序讀取記錄並且不需要滾動和更新記錄,最好使用服務器端游標(adUseServer)、僅向前游標(adOpenForwardOnly)和讀加鎖(adLockReadOnly),這樣可以獲得最好的性能。如果需要滾動記錄,采用客戶端游標(adUseServer)會比采用服務器端游標所得到的性能要好,因為ADO系統默認是采用服務器端游標類型。當然如果數據集合相當大,采用服務器端游標的性能會好一些。同時需要注意:如果采用客戶端游標,最好只采用讀加鎖(adLockReadOnly)的鎖類型,因為如果需要更新數據,客戶端游標引擎需要得到額外的信息(元數據),而獲取這個信息的代價是非常昂貴的。
ADO使用記錄集對象的CacheSize屬性來決定提取和緩存的記錄的數目,當在緩存的范圍內瀏覽數據時,ADO就只從緩存中提取數據。當要瀏覽的數據超出緩存范圍的時候,ADO就釋放當前緩存,提取下一些記錄(提取的數目為CacheSize所指定的大小),所以必須根據具體的應用程序的情況,來設定CacheSize的大小,保證得到最佳的性能。
在許多數據源中,得到參數信息和執行命令的代價幾乎是一樣的,所以最好自己在程序中定義好Command參數(也就是說要定義好參數的名稱、類型和方向信息),避免一些從數據提供者(Provider)那里獲取信息的操作。
MDAC對許多數據源提供了原始的數據提供者,比如SQL Server、Oracle和Access數據庫,這樣就不需要再通過ODBC來獲取數據(也就是說不需要再通過ODBC驅動這一層),這樣的好處是能更快地得到數據,並且能降低磁盤和內存的開銷。
如果使用客戶端游標,就要斷開Connection連接。ADO有一個特征是當使用客戶端游標操作 Recordset記錄集的時候,不需要和服務器保持聯系。所以可以充分利用這個特性降低服務器端的開銷(服務器就不需要維護這些連接了)。當操作完記錄集需要更新時,可以重新和數據庫進行連接來更新數據。為了創建一個可以斷開連接的記錄集,同時需要使用靜態游標(adOpenStatic)和
批處理
的加鎖模式(adLockBatchOptimistic)。下面是有關處理的VC代碼:
點擊(此處)折疊或打開
- pRs.CreateInstance(__uuid(Recordset));
- pRs->CursorLoction=adUseClient;
- pRs->Open(strCmdText,strConnection,adOpenStatic,adLockBatchOptimistic,adCmdText);
- pRs->PutRefActiveConnection(NULL);
- //對記錄集對象pRs進行操作
- //重新和數據庫建立連接
- pRs->PutRefActiveConnectio(pCon);
- //批量更新數據
- pRs->UpdateBatch(adAffectAll);
需要注意的是:當執行批量更新時,必須自己處理數據沖突問題,因為更新數據時,其他用戶也可能同時正在對該數據進行操作。11.使用adExecuteNoRecords選項
如果不需要返回記錄,要使用adExecuteNoRecords選項。ADO 2.0包括一個新的執行選項稱為adExecuteNoRecords。當使用該選項的時候,ADO就不會創建記錄集對象,不設置任何游標屬性。數據提供者因為不需要認證集合的屬性而使性能得到優化。具體的例子如下:
con.Execute “insert into tbl values(fv1, fv2) ”, , adExecuteNoRecords
對僅有一條的執行語句采用Connection::Execute方法比使用Recordset::Open方法或者是Command::Execute方法的效果要好,因為ADO不保留任何命令狀態的信息,因此執行性能就有所改進。
因為數據庫的打開和關閉非常消耗
系統資源
,因此,使用連接池對基於多層的應用的性能會有很大的提高。當使用MDAC的時候,開發人員本身並不需要考慮對數據庫連接的緩存,MDAC會自動處理它。連接池在兩個層次上提供支持:OLE DB sessions和ODBC連接。如果使用ADO,數據庫連接會自動被OLE DB session緩沖池所緩存;如果使用ODBC,可以利用在
ODBC數據源
管理中新的連接緩沖池選項對ODBC緩沖進行設置。
實現方法
我們知道,在VB下進行基於ADO的編程相對比較簡單,只要通過reference加載了適當的類型庫后,就可以正常地調用ADO對象。但是對於VC下的基於ADO的數據庫開發就稍微復雜一些。VC中實現對ADO操作通常有三種方法:
?#import方法;
?利用MFC OLE的ClassWizard;
在這三種方法中,#import是最方便的方法,它允許產生一個類似VB的類結構,使程序開發變得很方便。下面分別介紹這三種方法。
1.#import方法
在#import方法中,需要提供所要包含的類型庫的路徑和名稱,VC能夠自動產生一個對GUIDs的定義,以及自動生成對ADO對象的封裝。對任何引用的類型庫,VC會在編譯的時候自動生成兩個文件:
?頭文件(.tlh):包含了所列舉的類型和對類型庫中對象的定義;
?實現文件(.tli):對類型庫對象模型中的方法產生封裝。
#import之后,VC會產生msado15.tlh和msado15.tli兩個文件。
#import能夠使用一個新的類_com_ptr_t,它也被稱為智能指針。智能指針能夠自動執行QuyerInterface、AddRef和Release函數。
下面的代碼演示了如何使用#import在應用中實現對ADO的操作:
#import “c:\program files\common files\system\ado\msado15.dll” \no_namespace
rename ( “EOF”, “adoEOF” )
重命名EOF是必要的,因為典型的VC應用都已經定義了EOF作為常數-1。
通常來說,操作一個自動化對象需要定義和初始化一個用來操作的變量。可以通過使用智能指針
(_com_ptr_t)的構造函數傳遞一個有效的CLSID或者是PROGID,也可以通過_com_ptr_t::CreateInstance()方法來定義對象。具體代碼如下所示:
點擊(此處)折疊或打開
- _ConnectionPtr Conn1( __uuidof( Connection ) );
也可以采用下面的代碼實現同樣的功能:
點擊(此處)折疊或打開
- _ConnectionPtr Conn1 = NULL; //定義對象
- HRESULT hr = S_OK;
- //創建實例
- hr =Conn1.CreateInstance( __uuidof( Connection ) );
推薦采用第二種方式,因為用第一種方式不能返回一個失敗的HRESULT,所以也就不能判斷ADO連接對象是成功還是失敗,以及失敗的原因。注意這里的__uuidof( Connection)中的Connection是在.tlh文件中定義的。通過把它傳遞給方法CreateInstance,就可以創建一個有效的 ADOConnection對象。
需要注意的是#import的no_namespace屬性,它告訴編譯器該類在不在一個單獨的名字空間中。使用no_namespace意味着不需要在初始化變量時引用名字空間。當然如果在應用中需要導入多個類型庫時,最好不要使用 no_namespace,以免引起名字沖突。
下面是一個簡單的采用了#import方法的基於ADO應用的示例代碼:
點擊(此處)折疊或打開
- #import “c:\program files\common files\system\ado\msado15.dll” rename(“EOF”, “adoEOF”)
- void main()
- {
- HRESULT hr = S_OK;
- //因為沒有在#import中指定no_namespace,所以必須采用ADODB::這樣的形式來定義變量類型
- ADODB::_RecordsetPtr Rs1 = NULL;
- //通過ODBC建立ADO連接
- _bstr_t Connect( “DSN=AdoDemo;UID=sa;PWD=;” );
- _bstr_t Source ( “SELECT * FROM Authors” );
- CoInitialize();
- //初始化Rs1對象
- hr = Rs1.CreateInstance( __uuidof( ADODB::Recordset ) );
- //省略對返回值hr的判斷
- Rs1->Open( Source,
- Aonnect,
- ADODB::adOpenForwardOnly,
- ADODB::adLockReadOnly,
- -1 );
- //此處可以添加對記錄集Rs1進行操作的代碼
- Rs1->Close();
- Rs1 = NULL;
- ::MessageBox( NULL,“Success!”,“”,MB_OK );
- CoUninitialize();
- }
用MFC OLE創建ADO應用
MFC OLE同樣能夠封裝(wrapper)一個類型庫,但是與#import不同,它不能從類型庫中產生枚舉類型。MFC類CString和 COleVariant隱藏了BSTRS和Variants的細節。由MFC OLE產生的類都繼承了類ColeDispatchDriver,由ADO產生的失敗的HRESULTS被封裝在類 ColeDispatchException中。
用MFC OLE ClassWizard創建ADO應用的步驟如下:
?從Tools菜單中,選擇Options選項中的Directories tab條目,在Show Directories中的Library Files中增加路徑C:\program files\common files\system\ado,設置包含ADO類型庫的路徑。
?從View菜單中,激活ClassWizard,點擊Add Class按鈕並選擇“From A Type Library...”選項,然后在Type Library dialog box對話框中,從C:\program files\common files\system\ado中選擇文件msado15.dll,在Confirm Classes對話框中,選擇所有列出的類並按OK按鈕退出ClassWizard。這樣,ClassWizard便生成了兩個文件msado15.h和 msado15.cpp。
下面是實現ADO應用的示例代碼:
點擊(此處)折疊或打開
- //初始化COM對象
- AfxOleInit();
- ...
- //定義數據集對象
- _Recordset Rs1;
- COleException e;
- COleVariant Connect( “DSN=AdoDemo;UID=sa;PWD=;” );
- COleVariant Source ( “SELECT * FROM Authors” );
- //創建數據集對象
- Rs1.CreateDispatch(“ADODB.Recordset.2.0”,&e );
- Rs1.Open( (VARIANT) Source,
- (VARIANT) Connect,
- 0, 1, -1 );
- //此處可以添加對結果集Rs1進行處理的代碼
- Rs1.Close();
- Rs1.ReleaseDispatch();
- AfxMessageBox(“Success!”);//初始化COM對象
- AfxOleInit();
- ...
- //定義數據集對象
- _Recordset Rs1;
- COleException e;
- COleVariant Connect( “DSN=AdoDemo;UID=sa;PWD=;” );
- COleVariant Source ( “SELECT * FROM Authors” );
- //創建數據集對象
- Rs1.CreateDispatch(“ADODB.Recordset.2.0”,&e );
- Rs1.Open( (VARIANT) Source,
- (VARIANT) Connect,
- 0, 1, -1 );
- //此處可以添加對結果集Rs1進行處理的代碼
- Rs1.Close();
- Rs1.ReleaseDispatch();
- AfxMessageBox(“Success!”);
用COM API創建ADO工程
#import和MFC OLE都圍繞着一個給定的自動化對象產生了一個封裝類,它們分別繼承自_com_ptr_t和ColeDispatchDriver。其實也可以通過使用 Windows API函數直接初始化ADO對象。為了直接使用ADO和COM對象,需要添加兩個頭文件adoid.h和adoint.h,這兩個頭文件定義了 CLSIDs、接口定義和操作ADO類型庫所需要的枚舉類型。此外,還需要增加頭文件INITGUID.H。
為了能夠編譯用COM API創建的ADO工程文件,還需要在機器中安裝OLE DB SDK或者是MSDASDK工具。下面是利用API創建ADO的簡單的示例代碼:
點擊(此處)折疊或打開
- #include “adoid.h” // ADO的GUID's
- #include “adoint.h” // ADO的類、枚舉等等
- void main()
- {
- HRESULT hr = S_OK;
- // ADORecordset 是在adoint.h中定義的
- ADORecordset*Rs1 = NULL;
- VARIANT Source;
- VARIANT Connect;
- VariantInit( &Source );
- VariantInit( &Connect );
- Source.vt = VT_BSTR;
- Source.bstrVal = ::SysAllocString( L“SELECT * FROM Authors”);
- Connect.vt = VT_BSTR;
- Connect.bstrVal = ::SysAllocString( L“DSN=AdoDemo;UID=sa;PWD=;” );
- hr = CoCreateInstance( CLSID_CADORecordset,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_IADORecordset,
- (LPVOID *) &Rs1 );
- if( SUCCEEDED( hr ) ) hr = Rs1->Open
- (Source,
- Connect,
- adOpenForwardOnly,
- adLockReadOnly,
- -1 );
- //對記錄集Rs1進行處理
- if( SUCCEEDED( hr ) ) hr = Rs1->Close();
- if( SUCCEEDED( hr ) ) { Rs1->Release(); Rs1 = NULL; }
- if( SUCCEEDED( hr ) ) ::MessageBox( NULL, “Success!”, “”, MB_OK );
- }
C++ Extensions
如果用C++進行ADO
應用程序開發
,應該使用ADO C++ Extensions。我們知道,用VB或者VBScript來操作ADO是非常方便的,但是如果使用C++或者是Java,就必須要處理類似 Variants這樣的
數據結構
以實現和C++數據結構的轉換,而這種處理無疑是所有C++開發人員都很頭疼的事情。但如果使用C++ Extensions的話,ADO就不需要從數據提供者處得到列信息,而是在設計時刻使用開發人員提供的列信息。以下是一個簡單的示例:
點擊(此處)折疊或打開
- //創建和具體記錄相對應的類
- class CAuthor : public CADORecordBinding
- {
- BEGIN_ADO_BINDING(CCustomRs1)
- ADO_VARIABLE_LENGTH_ENTRY4(1,
- adVarChar, m_szau_id, sizeof(m_szau_id), FALSE)
- ADO_VARIABLE_LENGTH_ENTRY4(2,
- adVarChar,m_szau_fname,sizeof(m_szau_fname), FALSE)
- ADO_VARIABLE_LENGTH_ENTRY4(3,
- adVarChar,m_szau_lname,sizeof(m_szau_lname), FALSE)
- END_ADO_BINDING()
- protected:
- char m_szau_id[12];
- char m_szau_fname[21];
- char m_szau_lname[41];
- };
- void FetchAuthorData()
- {
- CAuthor author;
- //記錄集對象
- _RecordsetPtr pRs;
- IADORecordBinding *piAdoRecordBinding;
- //獲取COM對象接口指針
- pRs.CreateInstance(__uuidof(Recordset));
- //得到需要的記錄集
- pRs->Open(“select au_id,au_fname,au_lname from Employees”,“Provider=SQLOLEDB;Data Source=sureshk1;Database=pubs;User Id=sa;Password=;”,
- adOpenForwardOnly,
- adLockReadOnly,
- adCmdText);
- //查詢接口IADORecordBinding
- pRs->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*)&piAdoRecordBinding);
- //綁定對象
- piAdoRecordBinding->BindToRecordset(&author);
- //得到記錄中的相關內容
- while (VARIANT_FALSE == pRs->EOF) {
- printf(“%s %s %s”, author.m_szau_id,
- author.m_szau_fname, author.m_szau_lname);
- pRs->MoveNext();
- }
- //釋放對象
利用ADO ACCESS數據庫
ACCESS是一個關系型
桌面
數據庫管理系統
,它可以用來建立中小型號的
數據庫應用系統
,使用非常廣泛.下面介紹如何使用ADO連接ACCESS數據庫.在連接數據庫時,需要使用Connection對象的Open方法打開與數據源的連接.
語法:Connectoin.open Connectionstring,userID,password,openoptions
Open方法的參數表說明如下
Open方法參數說明
ConnectionString (可選)字符串,包含連接信息,參照(ConnectionSting)屬性可獲得有效調協的詳細信息
UserID (可選)字符串,包含建立連接時所使用的用戶名稱
Password (可選)字符串,包含建立連接時所用的密碼
openoptions (可選)ConnectionEnum值.如果調協為adConnectoAsync,則異步打開連接,當連接可用時將產生ConnectComplete事件
ADO(ActiveX Data Objects)是一種操作 Microsoft 所支持的數據庫的新技術。在 ASP 中,ADO可以看作是一個服務器組件(Server Component),更簡單點說,是一系列的對象,應用這些功能強大的對象,即可輕松完成對數據庫復雜的操作。本文中個性化頁面的實現便大量地用到了 ADO 技術。具體的操作步驟可以歸納為以下幾步:
(1) 創建數據庫源名(DSN)
(2) 創建數據庫鏈接(Connection)
(3) 創建數據對象
(4) 操作數據庫
(5) 關閉數據對象和鏈接