人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當前位置:蘿卜系統下載站 > 技術開發教程 > 詳細頁面

ADO編程應用(1)

ADO編程應用(1)

更新時間:2021-04-09 文章作者:未知 信息來源:網絡 閱讀次數:

ADO(ActiveX Data Objects)是基于組件的數據庫編程接口,它是一個和編程語言無關的COM組件系統。本文主要介紹用ADO編程所需要注意的技巧和在VC下進行ADO編程的模式,并對C++ Extensions進行了簡單的討論,希望對ADO開發人員有一定的幫助作用。因為ADO是一個和編程語言無關的COM組件系統,所以這里討論的要點適用于所有的編程語言和編程環境,比如:VB、VBScript、VC、Java等等。
編程技巧
1.顯式定義對象類型
實際上,這條準則不僅適用于ADO編程,也適用于其他的與COM對象相關的編程。因為如果一開始就定義變量類型,則編譯器在編譯的時候就可以知道變量的類型,此時編譯器實際上是采用vtable偏移的方式來得到具體的COM對象包含的方法的地址(這一點和C++中虛函數的地址獲取方式類似);但如果一開始不指定變量類型的話,比如簡單地采用如下的語句:
DIM myCon as Object
或者是:
DIM myCon
這樣,編譯器在編譯的時候就不能得到變量的類型,而只能在運行的時候動態地得到方法的信息(通過使用接口IDispatch的Invoke方法來實現),如此為了得到方法的地址和相關的變量情況就需要在內部進行兩次調用,無疑會降低程序的運行速度。
2.綁定列到具體的字段對象
在程序開始時就建立對字段對象的引用,可以避免在每次得到記錄后,再在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
3.用SQL語句和存儲過程進行數據更新
盡管采用Recordset對象來更新數據是非常方便的,但是它的開銷也大,通過數據源對象返回的查詢集不僅包含了數據,而且也包含了元數據(metadata),在有些時候元數據可能比數據本身還要大,所以最好采用SQL語句來更新數據。還有要使用存儲過程而不是單一的SQL語句來獲取信息。因為存儲過程是在服務器端執行的,只把結果返回到客戶端,這樣一方面可以降低網絡進行數據交互的開銷,另一方面使系統更加容易維護,并且能保持數據的一致性。
4.使用集合操作單條的SELECT語句
在使用游標時,最好使用集合的方法對單條的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
5.只查詢所需要的數據
盡管很多開發人員都習慣采用“SELECT * FROM TBL”的模式進行查詢,但是為了提高系統的效率,如果只需要其中某幾個字段的值,最好把這幾個字段直接寫出來,同時需要限定返回記錄集的范圍(通過WHERE子句進行限定)。
6.正確選擇游標的位置、類型和鎖方式
如果只需要按順序讀取記錄并且不需要滾動和更新記錄,最好使用服務器端游標(adUseServer)、僅向前游標(adOpenForwardOnly)和讀加鎖(adLockReadOnly),這樣可以獲得最好的性能。如果需要滾動記錄,采用客戶端游標(adUseServer)會比采用服務器端游標所得到的性能要好,因為ADO系統默認是采用服務器端游標類型。當然如果數據集合相當大,采用服務器端游標的性能會好一些。同時需要注意:如果采用客戶端游標,最好只采用讀加鎖(adLockReadOnly)的鎖類型,因為如果需要更新數據,客戶端游標引擎需要得到額外的信息(元數據),而獲取這個信息的代價是非常昂貴的。
7.調整記錄集對象的CacheSize屬性
ADO使用記錄集對象的CacheSize屬性來決定提取和緩存的記錄的數目,當在緩存的范圍內瀏覽數據時,ADO就只從緩存中提取數據。當要瀏覽的數據超出緩存范圍的時候,ADO就釋放當前緩存,提取下一些記錄(提取的數目為CacheSize所指定的大小),所以必須根據具體的應用程序的情況,來設定CacheSize的大小,保證得到最佳的性能。
8.定義Command對象的參數
在許多數據源中,得到參數信息和執行命令的代價幾乎是一樣的,所以最好自己在程序中定義好Command參數(也就是說要定義好參數的名稱、類型和方向信息),避免一些從數據提供者(Provider)那里獲取信息的操作。
9.使用原始的OLE DB提供者
MDAC對許多數據源提供了原始的數據提供者,比如SQL Server、Oracle和Access數據庫,這樣就不需要再通過ODBC來獲取數據(也就是說不需要再通過ODBC驅動這一層),這樣的好處是能更快地得到數據,并且能降低磁盤和內存的開銷。
10.斷開Connection連接
如果使用客戶端游標,就要斷開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不保留任何命令狀態的信息,因此執行性能就有所改進。
12.使用session/connection緩沖池
因為數據庫的打開和關閉非常消耗系統資源,因此,使用連接池對基于多層的應用的性能會有很大的提高。當使用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;
●通過Windows API中COM相關的函數。
在這三種方法中,#import是最方便的方法,它允許產生一個類似VB的類結構,使程序開發變得很方便。下面分別介紹這三種方法。
1.#import方法
在#import方法中,需要提供所要包含的類型庫的路徑和名稱,VC能夠自動產生一個對GUIDs的定義,以及自動生成對ADO對象的封裝。對任何引用的類型庫,VC會在編譯的時候自動生成兩個文件:
●頭文件(.tlh):包含了所列舉的類型和對類型庫中對象的定義;
●實現文件(.tli):對類型庫對象模型中的方法產生封裝。
例如,在stdafx.h文件中增加對msado15.dd的#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,以免引起名字沖突。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統下載排行

網站地圖xml | 網站地圖html
主站蜘蛛池模板: 东丽区| 伊金霍洛旗| 镇江市| 启东市| 五寨县| 台前县| 保山市| 措勤县| 酒泉市| 遂溪县| 当涂县| 霸州市| 靖宇县| 陕西省| 茂名市| 永仁县| 鸡西市| 舟曲县| 安徽省| 奇台县| 闽清县| 潞西市| 壶关县| 鄱阳县| 梓潼县| 阿勒泰市| 海安县| 龙南县| 仁寿县| 炎陵县| 福贡县| 祁阳县| 望城县| 溧水县| 新昌县| 桃园县| 玛纳斯县| 青海省| 繁昌县| 紫阳县| 通州市|