版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、1.編寫桌面數(shù)據(jù)庫應用1.1. 使用數(shù)據(jù)集數(shù)據(jù)集是以行和列的形式組織起來的數(shù)據(jù)的集合。其中,每一列具有相同的數(shù)據(jù)類型,而每行是由各列指定類型的數(shù)據(jù)組成的。數(shù)據(jù)集的每一列被稱為一個字段,每一行被稱為一個記錄。V C L把數(shù)據(jù)集封裝在一個稱為TDataSet的抽象組件中。在TataSet中引入了許多用于操作和瀏覽數(shù)據(jù)集的屬性和方法。1.1.1 VCL的數(shù)據(jù)庫體系結(jié)構(gòu)在開發(fā)Delphi 3期間,V C L的數(shù)據(jù)庫體系結(jié)構(gòu)已經(jīng)有了令人注目的修改,為了在D e l p h i程序中能方便地訪問一些非B D E的數(shù)據(jù)集,它開放了數(shù)據(jù)集體系結(jié)構(gòu)。T D a t a S e t類位于整個體系結(jié)構(gòu)的頂層。T D
2、 a t a S e t是一個用來抽象地表示數(shù)據(jù)集的記錄和字段的組件。為了實現(xiàn)對一些特殊的物理數(shù)據(jù)格式的訪問,你可以在程序中覆蓋T D d a t a S e t類的方法。1.1.2 BDE數(shù)據(jù)訪問組件在組件面板的Data Access頁上可以找到用于訪問和管理B D E數(shù)據(jù)集的V C L組件,如圖2 8 - 1所示。V C L用三種組件來表達數(shù)據(jù)集: T Ta b l e、T Q u e r y和T S t o r e d P r o c。T Ta b l e是表達數(shù)據(jù)庫表中的數(shù)據(jù)和結(jié)構(gòu)的組件; T Q u e r y是利用S Q L對數(shù)據(jù)進行查詢并返回數(shù)據(jù)集的組件。T S t o r e
3、P r o c是封裝了S Q L服務(wù)器上的一個存儲過程的組件。本章中,我們將使用T Ta b l e組件討論數(shù)據(jù)集。稍后再介紹T Q u e r y組件。1.1.3 打開一個數(shù)據(jù)集如果是訪問S Q L服務(wù)器,那么在打開數(shù)據(jù)庫中的一個數(shù)據(jù)集之前,一定要先建立數(shù)據(jù)庫連接。當你關(guān)閉掉數(shù)據(jù)庫中最后一個數(shù)據(jù)集時,連接就會終止。建立和斷開數(shù)據(jù)庫的連接都會有一些開銷。如果你經(jīng)常執(zhí)行開關(guān)數(shù)據(jù)庫的操作,那么應該利用T D a t a b a s e組件來管理對S Q L服務(wù)器的連接。在對數(shù)據(jù)集進行操作之前,必須先將它打開。我們用O p e n ( )方法來實現(xiàn)。請看示例:Table1.Open();你也可以通過
4、將數(shù)據(jù)集的A c t i v e屬性設(shè)為Tr u e來打開它:Table1.Active:=True;使用第二種方法的開銷更小一些,因為利用O p e n ( )方法來實現(xiàn)最終還是要將數(shù)據(jù)集的A c t i v e屬性設(shè)為Tr u e。不過,這點小開銷可以忽略。當數(shù)據(jù)集被打開后,我們就可以自由地操作和使用它了。在一系列的操作完成后,不要忘記要調(diào)用C l o s e ( )方法將它關(guān)閉。如下:Table1.Close();當然,你也可以通過把A c t i v e屬性設(shè)為F a l s e來關(guān)閉數(shù)據(jù)集。例如:Table1.Active:=False;1.1.4 瀏覽數(shù)據(jù)集T D a t a S
5、e t提供了簡單的方法來瀏覽數(shù)據(jù)集中的記錄。First() 將當前的記錄指針定位在數(shù)據(jù)集中的第一個記錄;L a s t ( )把當前的記錄指針定位在數(shù)據(jù)集中的最后一個記錄; N e x t ( )和P r i o r ( )分別使當前記錄指針向前或向后移動一個記錄。另外, M o v e B y ( )方法用于向前或向后移動一定數(shù)量的記錄。. BOF、E O F和循環(huán)B O F和E O F都是T D a t a S e t中布爾類型的屬性,分別表示當前記錄是否是第一個記錄和最后一個記錄。例如,如果需要遍歷數(shù)據(jù)集中的每一條記錄,最容易實現(xiàn)的方法就是利用一個w h i l e循環(huán)來使
6、指針從第一個記錄不斷地向后移動直到E O F為真Table1.First;While not Table1.Eof do begin Do something; Table1.Next;End;. 書簽書簽能在數(shù)據(jù)集中保存當前的位置,以便以后可以回到那個位置。在D e l p h i中書簽的使用非常簡單,你只需要使用一個屬性。Delphi 用T B o o k m a r k S t r類型來表示書簽,T Ta b l e的Bookmark 屬性便是此種類型。當從B o o k m a r k中讀值時,你就獲取了一個書簽;當你寫到它時,就可以定位在書簽所指示的記錄位置。當你對數(shù)據(jù)
7、集的某個地方感興趣并且想能標記以便日后訪問時,Var BM:TBookMarkStr;/聲明Begin BM:=Table1.BookMark;/定義 Table1.BookMark:=BM;/ 回到這個書簽標記的位置 BM:=;End. TDataSource我們在前面的程序中用到了T D a t a S o u r c e組件,所以我們將在這里詳細討論這個組件。T D a t a S o u r c e是一個數(shù)據(jù)庫連接中介,它使數(shù)據(jù)訪問組件(如T Ta b l e )能向數(shù)據(jù)感知組件提供數(shù)據(jù)。它不但在數(shù)據(jù)訪問和數(shù)據(jù)感知兩方面起到了接口的作用,而且,它還包含了一些使數(shù)據(jù)操作變得
8、更簡單的屬性和事件。l T D a t a S o u r c e的S t a t e屬性表示當前連接的底層數(shù)據(jù)集的狀態(tài)。它可以表明數(shù)據(jù)集是處于未活動的狀態(tài)還是插入、編輯、設(shè)置鍵值或是計算字段狀態(tài)。l S t a t e屬性的值的變化會導致發(fā)出O n S t a t e C h a n g e事件。T D a t a S e t的O n D a t a C h a n g e事件是在數(shù)據(jù)集變成活動狀態(tài)或數(shù)據(jù)感知組件通知數(shù)據(jù)集數(shù)據(jù)發(fā)生改變時被觸發(fā)。l On U p d a t e D a t a事件在記錄被提交或更新時被觸發(fā),在處理此事件時,一般會改變數(shù)據(jù)感知組件顯示的數(shù)據(jù),這種改變依賴于數(shù)據(jù)庫
9、表的內(nèi)容。響應此事件你可以使跟蹤程序中類似的改變。1.1.5 對字段操作. 字段值訪問字段的值需要用到T D a t a s e t的數(shù)組屬性F i e l d s 或F i e l d s B y N a m e ( )函數(shù)。l F i e l d s 0 將返回一個T F i e l d對象,它表示數(shù)據(jù)集的第一個邏輯字段。S:=Table1.Fields0.AsStringl F i e l d s B y N a m e ( )函數(shù)需要輸入字段名作為參數(shù),并返回一個字段對象。S:= Table1.FieldsByName(Name).AsString;. 字段
10、數(shù)據(jù)類型T F i e l d的D a t a Ty p e屬性可以告訴你字段的類型,所返回的字段類型只與數(shù)據(jù)庫類型有關(guān),與O b j e c tP a s c a l的數(shù)據(jù)類型無關(guān)。字段名和編號l 利用T F i e l d的F i e l d N a m e屬性能得到某個字段的字段名。S:=Table1.Fields0.FieldName;l 利用F i e l d N o屬性可以獲取某個字段對應的編號。S:= Table1.FieldsByName(Name).FieldNo;. 操作字段數(shù)據(jù)l 編輯Table1.Edit;Table1.FieldByName
11、(Name).AsString:=LTMa;Table1.Post;Table1.Cancle;/也可以用Cancle來取消操作l 插入Table1.Insert;/或者Table1.AppendTable1.FieldByName(Name).AsString:=LTMa;Table1.Post;Table1.Cancle;/也可以用Cancle來取消操作l 刪除Table1.Last;Table1.Delete;數(shù)據(jù)集在插入、添加或編輯狀態(tài)時,記住,只要離開當前記錄,對數(shù)據(jù)的改變就會被提交給數(shù)據(jù)庫。因此,在編輯數(shù)據(jù)時要小心使用N e x t ( )、P r i o r ( )、F i r
12、s t ( )、L a s t ( )或M o v e B y ( )等方法。我們可以利用C a n c e l ( )方法來取消當前對數(shù)據(jù)集的修改。C a n c e l ( )方法不但取消了對數(shù)據(jù)的修改,也同時取消了當前數(shù)據(jù)集的模式狀態(tài),回到了瀏覽模式1.1.6 刷新數(shù)據(jù)集編寫數(shù)據(jù)庫程序時,一定要清楚地認識到,數(shù)據(jù)集中的數(shù)據(jù)是一直在變化的。這就是說,數(shù)據(jù)集中的數(shù)據(jù)將會不斷地被添加、刪除或修改,尤其是對于網(wǎng)絡(luò)環(huán)境。因此,你必須不停地從磁盤或內(nèi)存中重新讀取數(shù)據(jù)集中的信息來更新當前所使用的數(shù)據(jù)集。更新數(shù)據(jù)集,可以使用TDataset 的R e f r e s h ( )方法。對R e f r e
13、 s h ( )的調(diào)用相當于先調(diào)用C l o s e ( )方法,再調(diào)用O p e n ( )方法,但是調(diào)用R e f r e s h ( )方法要快一些。R e f r e s h ( )方法適用于所有的本地表;而對于來自S Q L數(shù)據(jù)庫服務(wù)器的數(shù)據(jù)庫,R e f r e s h ( )方法使用起來有些限制。在B D E試圖進行R e f r e s h ( )操作之前,必須對S Q L數(shù)據(jù)庫表和查詢定義一個唯一的索引。其原因是,R e f r e s h ( )的調(diào)用總是盡可能保持記錄當前的狀態(tài)。所以, B D E必須使用S e e k ( )來定位到當前的位置,而S e e k ( )操
14、作只對S Q L數(shù)據(jù)集適用,而且要求有一個唯一的索引。R e f r e s h ( )并不工作于連接到S Q L數(shù)據(jù)庫的T Q u e r y組件。1.1.7 變化的狀態(tài)有時候,需要知道一個數(shù)據(jù)庫表當前為編輯模式還是添加模式,或是否處于活動狀態(tài),這些信息都可以通過查看TDataset 的S t a t e屬性來獲取。S t a t e屬性的類型為T D a t a S e t S t a t e,1.1.8 過濾器如果利用過濾器,只要使用Object Pascal代碼就能實現(xiàn)一些簡單的數(shù)據(jù)搜索或過濾。使用過濾器最主要的好處是不需要索引,也不需要對數(shù)據(jù)集做任何其他的準備工作。當然,過濾器和基于
15、索引的查找比起來,速度還是稍微慢一些(本章后面將會討論),但另一方面,它們對于任何類型的應用程序都非常有用。. 過濾一個數(shù)據(jù)集D e l p h i過濾機制的一個比較普遍的作用是只顯示數(shù)據(jù)集中的一些特定記錄。這是一個簡單的兩步操作:1) 創(chuàng)建一個處理數(shù)據(jù)集的O n F i l t e r R e c o r d事件的過程。在這個過程中,根據(jù)一個或多個字段的值來決定是否要包含某個記錄。2) 將數(shù)據(jù)集的F i l t e r d屬性設(shè)為Tr u e。. FindFirst/FindNextT D a t a S e t還提供F i n d F i r s t ( )、F
16、 i n d N e x t ( )、F i n d P r i o r ( )和F i n d L a s t ( )等方法。利用這些方法可以找出那些符合篩選條件的數(shù)據(jù)記錄。這些方法被O n F i l t e r R e c o r d事件處理過程調(diào)用,來對未經(jīng)過濾的數(shù)據(jù)集進行操作。根據(jù)O n F i l t e r R e c o r d事件處理過程中給出的過濾條件,可以找出第一個、下一個、前一個或最后一個匹配的記錄。每一個方法都不用輸入?yún)?shù),其返回值是一個表明是否找到匹配記錄的布爾值。. 定位一個記錄T D a t a S e t提供了一個名為L o c a t e (
17、)的方法。由于L o c a t e ( )使用過濾器進行查找,所以與數(shù)據(jù)集中的任何索引都沒有關(guān)系1.2 使用TTable組件1.2.1 查找記錄當需要查找數(shù)據(jù)庫表中的某些記錄時,可以使用V C L提供的若干方法。當使用d B A S E和P a r a d o x數(shù)據(jù)庫表時,Delphi 會假定被查找的字段都已經(jīng)被定義了索引。對S Q L數(shù)據(jù)庫表,如果所查找的字段沒有定義索引,那么查詢的效率將會很低以致于無法忍受。例如,如果為一個數(shù)據(jù)庫表建立了兩個索引,第一個索引基于字段1,它是數(shù)值類型的,第二個索引基于字段2,它是字母數(shù)字類型的。這樣就可以通過這兩個索引查找特定的記錄:即調(diào)用F i n d
18、 K e y ( )或者先調(diào)用S e t K e y ( )再調(diào)用G o t o K e y ( )。.1. FindKey()T Ta b l e組件的F i n d K e y ( )方法可用來查找一個與關(guān)鍵字段匹配的記錄。F i n d K e y ( )需要傳遞一個a r r a yof const類型的參數(shù)。如果調(diào)用成功,則返回Tr u e。例如,在下面的代碼中,記錄指針被定位在這樣的記錄,其第一個字段取值為1 2 3、第二個字段中包含h e l l o字符串。If Not Table1.FindKey(123,Hello) then MessageBeep(0);如果沒有找到匹配的
19、記錄,F(xiàn) i n d K e y ( )將返回F a l s e,并且計算機發(fā)出嘀的一聲。. SetKey()和G o t o K e y ( )T Ta b l e的S e t K e y ( )方法能夠使數(shù)據(jù)庫表進入設(shè)置鍵值的模式。在指定了查找條件后就可以調(diào)用G o t o K e y ( )來從頭到尾地搜索一個記錄。前面的例子如果改用S e t K e y ( ) . . G o t o K e y ( )來寫,則為:.3. 最接近的匹配F i n d N e a r e s t ( )與前面類似,你也可以調(diào)用F i n d N e a r e s t ( )來查找數(shù)據(jù)庫表
20、中與條件最接近匹配的記錄。例如要查找第一個字段與1 2 3最接近的記錄,并返回第一個匹配的記錄,可以使用下面的代碼:Table1.FindNearest(123);同樣,F(xiàn) i n d N e a r e s t ( )也需要傳遞一組常量作為輸入?yún)?shù),這些常量參數(shù)包含的是被查找的記錄的字段值。當查找成功時,如果K e y E x c l u s i v e屬性被設(shè)為F a l s e,則記錄指針將指在第一個匹配的記錄上;如果K e y E x c l u s i v e屬性被設(shè)為Tr u e,則記錄指針指在匹配的后一個記錄。.4. 使用哪個索引以上的方法都假設(shè)你想基于數(shù)據(jù)庫表的主索引來進行查找
21、。如果使用副索引進行查找,需要設(shè)置表對象的I n d e x N a m e屬性來指定一個索引。例如,如果數(shù)據(jù)庫表有一個基于C o m p a n y字段的副索引,名為B y C o m p a n y,下面的代碼查找U n i s c o公司:With Table1 do beginIndexName:=ByCompany;FindKey(Unisco);End注意在表打開的情況下,切換索引會有一些額外的開銷。如果在這時設(shè)置I n d e x N a m e屬性,可能會有一秒或更多的延遲。對于d B A S E表和P a r a d o x表來說,只能基于定義了索引的字段進行查找。對S Q
22、L數(shù)據(jù)庫來說,如果不是針對定義了索引的字段來設(shè)置范圍的話,性能將受到損害。.5. SetRange()和ApplyRange()與F i n d K e y ( )和F i n d N e a r e s t ( )類似,S e t R a n g e ( )可以進行復雜的操作。S e t R a n g e ( )需要傳遞兩組a r r a yof const類型的參數(shù),第一組參數(shù)表示字段取值范圍的下限,第二組則表示字段取值范圍的上限。下面的代碼從數(shù)據(jù)庫中過濾出那些第一個字段取值大于等于1 0并且小于等于1 5的記錄:Table1.SetRange(10,15);要使用A p p l y R
23、 a n g e ( )來設(shè)定取值范圍,可以按照下面的操作步驟:1) 調(diào)用S e t R a n g e S t a r t ( )方法,并修改數(shù)據(jù)庫表的F i e l d s 數(shù)組屬性來設(shè)置關(guān)鍵字段的起始值。2) 調(diào)用S e t R a n g e E n d ( )方法,并再次修改F i e l d s 數(shù)組屬性來設(shè)置關(guān)鍵字段的截止值。3) 調(diào)用A p p l y R a n g e ( )建立新的取值范圍過濾器。對前面的例子,可以這樣改寫:提示應該盡可能利用S e t R a n g e ( )來過濾記錄,因為這樣會使代碼更簡潔,而且出錯的可能性會更小。如果想要從一個數(shù)據(jù)庫表中取消一個范
24、圍過濾器,并且把數(shù)據(jù)庫恢復到調(diào)用App lyRange ( )前的狀態(tài),可以調(diào)用T Ta b l e組件的C a n c e l R a n g e ( )方法,代碼如下:2.開發(fā)C/S應用程序摘自DElPHI5開發(fā)人員指南第29章2.1 為什么要采用客戶/服務(wù)器結(jié)構(gòu)2.2 客戶/服務(wù)器體系結(jié)構(gòu)2.3 客戶/服務(wù)器模型2.4 客戶/服務(wù)器與桌面數(shù)據(jù)庫開發(fā)的比較 面向集合與面向記錄客戶程序并不是像桌面數(shù)據(jù)庫程序那樣直接面對數(shù)據(jù)庫表,而只是面對數(shù)據(jù)的子集。客戶程序在向服務(wù)器請求數(shù)據(jù)時,得到的數(shù)據(jù)可能是由一個或多個表中的字段構(gòu)成的,而請求是通過結(jié)構(gòu)化查詢語言( S Q L )實現(xiàn)的。通過S Q L,
25、客戶端可以限制從服務(wù)器返回的記錄數(shù)??蛻舳送ㄟ^S Q L語句從服務(wù)器上得到結(jié)果是服務(wù)器上的數(shù)據(jù)的一個子集。這一點很重要,因為對于桌面數(shù)據(jù)庫應用程序來說,它通過網(wǎng)絡(luò)所得到是整個數(shù)據(jù)庫表。顯然,數(shù)據(jù)庫表越大,網(wǎng)絡(luò)的流量就越大??蛻?服務(wù)器系統(tǒng)則不同,它只通過網(wǎng)絡(luò)傳送客戶請求的數(shù)據(jù),因而網(wǎng)絡(luò)流量較小,對網(wǎng)絡(luò)的要求也較低。這個區(qū)別也影響了對S Q L數(shù)據(jù)集的瀏覽性。例如第一條、最后一條、下一條和上一條記錄等概念,對基于S Q L的數(shù)據(jù)集來說不是固有的。尤其是當查詢結(jié)果是由多個數(shù)據(jù)庫表組成的情況下更是如此。許多S Q L服務(wù)器提供了可翻滾的指針,用于瀏覽S Q L結(jié)果集。盡管如此,這與桌面數(shù)據(jù)庫的瀏覽還
26、是不同的,因為后者直接針對數(shù)據(jù)庫表進行瀏覽。 數(shù)據(jù)安全S Q L數(shù)據(jù)庫處理數(shù)據(jù)安全的方式與桌面數(shù)據(jù)庫是不同的。S Q L數(shù)據(jù)庫不僅可以對數(shù)據(jù)庫進行口令驗證,而且還能夠針對特定的數(shù)據(jù)庫對象進行限制,包括視圖、數(shù)據(jù)庫表和存儲過程等。這意味著用戶訪問能夠在服務(wù)器端定義,來基于用戶的需要顯示數(shù)據(jù)。通常,S Q L數(shù)據(jù)庫允許通過G R A N T或R E V O K E命令向一個用戶或一組用戶授予或收回權(quán)限。因此,可以在S Q L數(shù)據(jù)庫中定義一組用戶。這些權(quán)限可以應用于任何一種已經(jīng)提到的數(shù)據(jù)庫對象。 記錄鎖定方法鎖定是一種機制,使得多個用戶可以對同一個數(shù)據(jù)庫提交并發(fā)的S Q L事務(wù)。鎖定級別有多種,不同
27、的服務(wù)器有不同的級別。表一級的鎖定主要用于限制對一個正在處理事務(wù)的數(shù)據(jù)庫表的訪問。盡管這種方式允許并行的處理,但這種鎖定機制速度很慢,因為多個用戶往往要共享同一個表。頁面級鎖定是一種改進的鎖定技術(shù)。用這種技術(shù),服務(wù)器可以把數(shù)據(jù)的某一塊鎖定在磁盤上,也就是所謂的頁面。當一個事務(wù)正在對某頁進行處理時,其他事務(wù)就不能更新該頁上的數(shù)據(jù)。由于數(shù)據(jù)往往分布在數(shù)百個頁面上,因此多個事務(wù)同時操作同一個頁面的可能性很小。有些服務(wù)器還提供了記錄級的鎖定機制,能夠鎖定數(shù)據(jù)庫表中的某一行。不過,這樣會大大增加鎖定信息的維護工作。桌面數(shù)據(jù)庫采用所謂的保守或明確的鎖定策略。這意味著,無法改變那些當前正在被其他用戶更新的記
28、錄。如果試圖訪問這樣的記錄,將會出錯,錯誤信息提示除非先前那個用戶釋放該記錄,否則無法訪問。S Q L數(shù)據(jù)庫采用所謂的優(yōu)化鎖定策略。這種技術(shù)并不限制訪問當前正在被其他用戶訪問的記錄,可以照常對它進行編輯,并請求服務(wù)器保存修改后的數(shù)據(jù)。不過,在記錄被保存之前,首先會與服務(wù)器中的備份進行比較,因為在查看和修改這條記錄的同時,它可能已被其他用戶更新。如果該記錄已被其他用戶修改,則會導致一個錯誤,提示在取得記錄后,它已經(jīng)被更新。作為一個開發(fā)人員,在設(shè)計客戶程序時應該考慮到這一點,客戶/服務(wù)器程序尤其要注意到這種情況,而在桌面數(shù)據(jù)庫中就不會發(fā)生。 數(shù)據(jù)完整性對于S Q L數(shù)據(jù)庫,可以對服務(wù)器中的數(shù)據(jù)進行
29、更健壯的完整性約束。盡管桌面數(shù)據(jù)庫也內(nèi)建了完整性驗證的功能,但需要在應用程序的代碼中定義一些業(yè)務(wù)規(guī)則。相對而言, S Q L數(shù)據(jù)庫允許在服務(wù)器端定義這些規(guī)則。這一點的好處是,不僅可以強制所有的客戶端程序都接受同一套規(guī)則的約束,而且可以集中維護這些規(guī)則。完整性約束是在服務(wù)器上創(chuàng)建數(shù)據(jù)庫表時定義的,完整性約束包括有效性、唯一性和參照性。完整性約束也可以在S Q L存儲過程中定義。例如,在處理一個訂單之前,可以先檢查顧客的信用。 面向事務(wù)S Q L數(shù)據(jù)庫是面向事務(wù)的。這意味著,對數(shù)據(jù)庫的修改不是像桌面數(shù)據(jù)庫那樣直接針對數(shù)據(jù)庫表進行的,而是由客戶請求服務(wù)器進行修改,服務(wù)器用一個事務(wù)來完成這一批操作。為
30、了確保對數(shù)據(jù)庫的修改能夠有效,必須完整地提交事務(wù)。如果事務(wù)中的任何一個操作失敗,整個事務(wù)就會被回滾,換句話說,就是放棄。事務(wù)能夠保證服務(wù)器上數(shù)據(jù)的一致性。還是以前面提到過的存貨系統(tǒng)為例,當顧客提交了一份訂單后,O R D E R S表必須更新。另外, PA RT S表也必須相應地把零件數(shù)減少。如果因為某種原因,系統(tǒng)在更新O R D E R S表和PA RT S表之間出錯,PA RT S表中的零件數(shù)就不能反映實際情況。但是,如果把整個操作放在一個事務(wù)中,除非整個事務(wù)正確地提交,否則,沒有一個表會有任何改變。在Delphi 5中,對于事務(wù)既可以在服務(wù)器層進行控制,也可以在客戶層進行控制。2.5 S
31、QL在客戶/服務(wù)器開發(fā)中的角色2.6 Delphi 客戶/服務(wù)器開發(fā)Delphi 5提供了一些數(shù)據(jù)庫對象組件,它們封裝了B D E的功能。這樣,開發(fā)數(shù)據(jù)庫應用程序就不必知道B D E的功能。其次, Delphi 5提供了數(shù)據(jù)感知組件可以與數(shù)據(jù)訪問組件彼此通信,這樣,建立數(shù)據(jù)庫應用程序的界面就變得簡單。SQL Links為連接O r a c l e、S y b a s e、I n f o r m i x、Microsoft SQL Server、D B 2和I n t e r B a s e提供了專門的驅(qū)動程序Delphi 5還包含了M I D A S技術(shù),“ M I D A S:Multiti
32、er Distributed Application Services Suite ”。最后, D e l p h i允許使用CORBA(Comman Object Request Broker Architecture) 來開發(fā)分布式應用程序。C O R B A規(guī)范已經(jīng)被OMG(Object Management Group)采用。通過C O R B A技術(shù),可以創(chuàng)建面向?qū)ο蟮姆植际綉贸绦?.7 服務(wù)器:后端設(shè)計2.8 客戶:前端開發(fā) 使用TDatabase組件T D a t a b s e組件可以更有效地控制數(shù)據(jù)庫的連接,包括: 建立一個永久的數(shù)據(jù)庫連接。 覆蓋默認的服務(wù)器登錄。 創(chuàng)建應
33、用程序級的B D E別名。 控制事務(wù)并指定事務(wù)的隔離級別。.1. 應用程序級的連接使用T D a t a b a s e組件的原因之一是,可以通過它建立一個應用程序級的別名。與B D E配置程序建立的別名不同的是,T D a t a b a s e組件建立的別名只在本項目中有效。如果要與其他應用程序共享這個別名,可以把T D a t a b a s e組件放到可共享的數(shù)據(jù)模塊( T D a t a M o d u l e )中,然后把數(shù)據(jù)模塊放到對象庫中,這樣,其他應用程序就可以使用它了。要建立一個應用程序級的別名,可以設(shè)置T D a t a b a s e . D a t a b a s e
34、 N a m e屬性。至于T D a t a b a s e要連接的數(shù)據(jù)庫的B D E別名則由T D a t a b a s e . A l i a s N a m e屬性來指定。.2. 安全控制T D a t a b a s e通過控制用戶的登錄過程來限制用戶對服務(wù)器數(shù)據(jù)的訪問。在登錄時,用戶必須給出合法的用戶名和口令才能訪問數(shù)據(jù)。默認情況下,當試圖連接數(shù)據(jù)庫時,會打開一個標準的對話框。處理登錄有幾種方式。首先,完全可以跳過登錄,讓用戶不需登錄就可以訪問服務(wù)器數(shù)據(jù)。其次,可以根據(jù)需要調(diào)出幾種不同的登錄對話框,以便在將用戶名和口令傳給服務(wù)器進行正常的檢查之前進行你自己的合法性檢查。最后,可以允
35、許用戶在不關(guān)閉應用程序的情況下退出再重新登錄。下面將詳細介紹這些技術(shù)。.2.1 自動登錄不讓登錄對話框出來如果不想出現(xiàn)登錄對話框,必須設(shè)置T D a t a b a s e的下列屬性:l A l i a s N a m e 設(shè)為一個已有的用B D E配置工具定義的B D E別名,通常與T Ta b l e、T Q u e r y組件的A l i a s屬性相同。l D a t a b a s e N a m e 設(shè)為一個應用程序級的別名,這個別名代表T Ta b l e、T Q u e r y或T S t o r e P r o c組件要訪問的數(shù)據(jù)庫。這些組件將使用該值作為它們的A l i a
36、 s屬性值。l L o g i n P r o m p t 設(shè)為F a l s e,這樣,T D a t a b a s e組件將從P a r a m s屬性中獲取用戶名和口令。P a r a m s 給出用戶名和口令。為此,必須打開一個字符串編輯器來設(shè)置這些值。l 設(shè)置了這些屬性后,必須把T Ta b l e、T Q u e r y或T S t o r e P r o c的A l i a s屬性值設(shè)為T D a t a b a s e的D a t a b a s e -N a m e屬性值,這樣,就把這些數(shù)據(jù)集組件與T D a t a b a s e連接起來。現(xiàn)在,可以把T D a t a
37、b a s e . C o n n e c t e d的屬性設(shè)為Tr u e。這樣,當應用程序連接到服務(wù)器時,將不提示輸入用戶名和口令,因為P a r a m s屬性中已經(jīng)給出了用戶名和口令。.2.2 自定義的登錄對話框在某些場合,可能需要為用戶提供自定義的登錄對話框。例如,你可能想提示用戶在對話框中輸入除了用戶名和口令之外的附加信息,或者希望在程序開始時能出現(xiàn)更漂亮的登錄對話框,而不是默認的那種。無論是何種情況,處理都非常簡單。l 首先,把T D a t a b a s e . L o g i n P r o m p t屬性設(shè)為Tr u e,這樣就不會顯示默認的登錄對話框, 并保證觸發(fā)O n
38、 L o g i n事件。l 不過,現(xiàn)在不要通過P a r a m s屬性提供用戶名和口令,而要編寫處理T D a t a b a s e . O n L o g i n事件的處理過程。這個事件處理過程在T D a t a b a s e . C o n n e c t e d屬性和T D a t a b a s e . L o g i n P r o m p t被設(shè)為Tr u e時被調(diào)用。下面的函數(shù)自定義了一個登錄窗口,并返回用戶名和密碼:.2.3 從當前會話退出.3 事務(wù)控制用Delphi 5編寫的客戶程序可以通過T D a t a b a s e的有關(guān)屬性和方法來處理事務(wù)。下面將介紹怎樣
39、在Delphi 5程序中處理事務(wù)。.3.1 隱式和顯式的事務(wù)控制Delphi 5既可以隱式又可以顯式地處理事務(wù),默認是隱式的。隱式的事務(wù)是以逐行的方式開始和提交的。這意味著,當調(diào)用P o s t方法或P o s t方法被V C L的代碼自動調(diào)用時,由于是逐行處理的,因此可能導致網(wǎng)絡(luò)流量增加,從而降低效率。顯式的事務(wù)處理又分下面兩種方式。l 一種方式是調(diào)用T D a t a b a s e組件的S t a r t Tr a n s a c t i o n ( )、C o m m i t ( )或R o l l B a c k ( )等方法;l 另一種方式是通過T Q u e r y組件的直通(
40、p a s s - t h r o u g h ) S Q L命令來實現(xiàn)的,由于顯式事務(wù)的網(wǎng)絡(luò)流量較小,而且代碼較安全,建議采用這種方式。.3.2處理事務(wù) T D a t a b a s e的方法中有三個是與數(shù)據(jù)庫事務(wù)有關(guān)的,分別是: S t a r t Tran s a c t i o n ( )、C o m m i t ( )和R o l l B a c k ( )。l S t a r t Tr a n s a c t i o n ( )啟動一個事務(wù),隔離級別由T D a t a b a s e . Tr a n s I s o l a t i o n屬性指定。在調(diào)用S t a r t T
41、r a n -s a c t i o n ( )之后對數(shù)據(jù)庫所做的任何修改都成為事務(wù)的一部分。l 如果對數(shù)據(jù)庫的所有修改都成功,則調(diào)用T D a t a b a s e . C o m m i t ( )方法把所有修改一次保存到數(shù)據(jù)庫中。l 反之,如果發(fā)生了錯誤,則調(diào)用T D a t a b a s e . R o l l B a c k ( )方法來取消所有的修改。.3.3 SQL直通模式S Q L直通( p a s s - t h r o u g h )模式能夠使Delphi 5數(shù)據(jù)庫應用程序與B D E共享到數(shù)據(jù)庫服務(wù)器的連接。Delphi 5的程序中如果調(diào)用了BDE API,則可能需要
42、使用B D E連接。直通模式是在B D E配置工具中設(shè)置的。這種模式有三個選項:l SHARED AUTO C O M M I T 以逐行方式處理數(shù)據(jù)庫事務(wù),主要用于桌面數(shù)據(jù)庫應用程序。在客戶/服務(wù)器環(huán)境下,這將導致網(wǎng)絡(luò)流量增加,因此不推薦這個選項,但這是Delphi 5應用程序的默認選項。l SHARED NOAUTO C O M M I T Delphi 5 程序必須通過調(diào)用T D a t a b a s e的S t a r t Tr a n s a c t i o n ( )、C o m m i t ( )和R o l l B a c k ( )方法來顯式地啟動、提交和回滾事務(wù)。l NO
43、T SHARED B D E和T Q u e r y組件提交的直通S Q L語句不共享同一個連接。這意味著, S Q L代碼可以不受B D E功能的限制,可以發(fā)揮服務(wù)器的特性。如果不想使用直通式S Q L但又想對事務(wù)進行更多的控制,可以把這個選項設(shè)為SHARED NOAUTOC O M M I T并自行處理事務(wù)。在大多數(shù)情況下,這種模式是可以的。但是,在多用戶環(huán)境下,如果某條記錄需要頻繁地更新,則可能發(fā)生沖突。.3.4 隔離級別隔離級別是指一個事務(wù)對其他事務(wù)正在訪問的數(shù)據(jù)具有怎樣的可見性。T D a t a b a s e . Tr a n s I s o l a t i o n屬性用于指定一
44、個事務(wù)的隔離級別。對于Tr a n s I s o l a t i o n屬性,可以有三種取值,分別代表三種隔離級別:l t i D i r R e a d 最低的隔離級別。具有該級別的事務(wù)可以讀取其他事務(wù)正在修改但還沒有提交的數(shù)據(jù)。l t i R e a d C o m m i t t e d 這是默認的隔離級別。具有該級別的事務(wù)只能讀取那些已被其他事務(wù)提交的數(shù)據(jù)。l t i R e p e a t a b l e R e a d 這是最高的隔離級別。具有這種隔離級別的事務(wù)無法讀到另一個事務(wù)正在讀取的數(shù)據(jù)。不同的服務(wù)器所支持的隔離級別也可能不同。Delphi 5通常使用t i R e a d
45、 C o m m i t t e d級別,除非服務(wù)器不支持該級別。 TQuery比TTable優(yōu)秀有人認為開發(fā)客戶/服務(wù)器結(jié)構(gòu)的前端與開發(fā)桌面數(shù)據(jù)庫應用程序是相同或類似的,這是一個較為普遍的錯誤認識。從使用T Ta b l e還是T Q u e r y的比較中,我們可以體會到這種區(qū)別。下面將討論使用T Ta b l e組件的優(yōu)缺點,分析在什么情況下應該使用它、什么情況下不應該使用它。通過這些分析,你將會理解為什么使用T Q u e r y組件比較好。l T Ta b l e組件能夠操作整個數(shù)據(jù)庫表、瀏覽前后的記錄或者轉(zhuǎn)到某個特定的記錄。不過,這些概念對S Q L數(shù)據(jù)庫服務(wù)器來說則是不適用的。關(guān)
46、系型數(shù)據(jù)庫是以數(shù)據(jù)集的形式被訪問的。因此, S Q L數(shù)據(jù)庫中沒有下一條記錄、前一條記錄和后一條記錄等概念。而在T Ta b l e組件中,這些概念是非常普遍的。盡管有些S Q L數(shù)據(jù)庫提供了可滾動的指針,但這不是標準的,l 當我們通過T Ta b l e組件操作S Q L數(shù)據(jù)庫時,最重要的一點就是,通過T Ta b l e組件發(fā)出的數(shù)據(jù)庫操作命令必須轉(zhuǎn)換為S Q L代碼才能被S Q L數(shù)據(jù)庫識別和執(zhí)行。這不僅限制了對數(shù)據(jù)庫的訪問,而且也大大降低了效率。l 雖然T Ta b l e的F i n d K e y ( )方法能夠搜索記錄,但對于S Q L數(shù)據(jù)庫來說此方法是有限制的。首先,F(xiàn) i n
47、 d K e y ( )只能基于定義了索引的字段進行搜索,而T Q u e r y則沒有這個限制,因為它是用S Q L來查詢記錄的。盡管TTable.FindKey( )最終還是用S E L E C T命令來對數(shù)據(jù)庫表進行操作的,但是,使用F i n d K e y ( )得到的結(jié)果集中包含了所有的字段,即使通過T Ta b l e的字段編輯器只選擇了其中部分字段。 使用TQuery組件3使用ADO摘自Master Delphi7第15章3.1Microsoft數(shù)據(jù)訪問組件(MDAC) 3.2使用dbGo組件 3.3使用Jet引擎 3.4光標 ADO集合有兩個基礎(chǔ)屬性會對程序產(chǎn)生基礎(chǔ)性的影響,
48、并且不可分割的相互鏈接在一起,它們是:CursorLocation和CursorType光標位置CursorLocation屬性運行程序員來指定誰控制數(shù)據(jù)的提取和更新,有兩個選擇:客戶機(clUseClient)和服務(wù)器(clUseServer)。所作的選擇會影響數(shù)據(jù)集合的功能、性能和可擴張性。.1客戶端光標(clUseClient)客戶端光標由ADO Cursor Engine負責管理,當數(shù)據(jù)集打開的時候數(shù)據(jù)從服務(wù)器提取到客戶端,并保存在內(nèi)存中,由ADO Cursor Engine管理更新和操作.2服務(wù)器端光標(clUseServer)光標類型.1只向前光標.2靜態(tài)光標.3鍵集光標.4動態(tài)光
49、標要求與結(jié)果無記錄計數(shù)客戶端索引IndexFieldName,ADO不從數(shù)據(jù)源讀數(shù),而是在內(nèi)存中完成的。復制Clone方法可以復制任意的ADO數(shù)據(jù)集合。復制不會影響到最初的地副本,它們擁有自己的記錄指針和其它狀態(tài)信息,并且可以擁有不同的Active記錄3.5事務(wù)處理 ADO的事務(wù)處理被ADOConnection組件控制,使用BeginTrasaction、CommitTrasaction、RollbackTrasaction嵌套事務(wù) ADOConnection屬性 鎖定類型ADO支持四種不同的方法來鎖定用于更新的數(shù)據(jù)(LockType有4種屬性),它們是:ltReadOnly,ltPessim
50、istic,ltOptimistic,ltBatchOptimistic.1 ltReadOnly:指定數(shù)據(jù)是只讀的,并且不能更新.2 ltPessimistic消極鎖定:消極鎖定假設(shè)用戶將有很大的可能性會同時更新相同的記錄,并出現(xiàn)沖突。為防止這樣的沖突,當編輯開始時記錄將被鎖定,并一直持續(xù)到更新完成或者取消操作為止。第二個試圖編輯相同記錄的用戶將不能成功鎖定記錄,并會收到一條“不能更新,當前記錄已被鎖定”的異常。l 優(yōu)點:用戶可以知道他們是否可以開始編輯一條記錄,以及是否能成功的保存他們的更新l 缺點:用戶在鎖定與接觸鎖定的時間上需要控制,防止用戶開始編輯一條記錄就離開了,而使此記錄一直被鎖
51、定。常用TTime設(shè)備,在鍵盤與鼠標休眠一定時間后解除鎖定。ltOptiimstic消極鎖定必須使用一個服務(wù)器端的光標。3.6更新數(shù)據(jù) 聯(lián)合查詢DataSet的更新ADO支持批更新,并且ADO的連接是天生可以“更新的”。在一個ADO連接中,每個字段對象都知道它屬于哪個數(shù)據(jù)庫表。例如由表Products和表Supplier連接查詢生產(chǎn)ADODataSetJointData,如果更新的字段屬于Products表,則會生成一條針對Products表的SQL Update語句。如果更新2個字段分別屬于Products表和Supplier表,則會生產(chǎn)2條分別針對Produts表和Supplier表的SQ
52、L Update語句ADO解決方案的最大問題是刪除一個連接的一行時,操作將會失敗。假如用戶只想刪除Products表的數(shù)據(jù),可以用下面代碼來指定刪除只針對Products表ADOQuery1.PropertiesUnique Table.Value:=Products;AdoQuery1.Recordset.Properties'Unique Table'.Value :='tablename' 批更新使用批更新的時候,對記錄做的任何修改都在內(nèi)存中進行,然后將整批的修改作為一個操作來提交,其用法如下:l 在打開數(shù)據(jù)集合前,
53、將LockType設(shè)為ltBatchOptimisticl 將CursorLocation設(shè)為clUseClient,因為批更新是由ADO的ADO Cursor Engine管理的。l 然后所有的修改作為增量,在內(nèi)存中進行l(wèi) 使用UpdateBatch,更新永久有效l 使用CancleBatch或CancleUpdate放棄整批的更新 ADO的其它重要屬性.1 UpdateStatusUpdateStatus用于識別記錄的狀態(tài)(插入、更新、刪除或未修改),它特別適用于在Grid中用不同顏色來突出記錄.2 UpdatesPendingADO數(shù)據(jù)集的UpdatesPending屬性,在數(shù)據(jù)集已經(jīng)修
54、改但是還沒有應用的時候為True,這在窗體的OnCloseQuery事件中用于提示還有未保存的數(shù)據(jù): Procedure TForm1.FormCloseQuery(Sender:TObject;var CanClose :Boolean) Begin CanClose:=True; If ADODataSet1.UpdatesPending then CanClose:=MessageDlg(); End;.3 FilterGroupADO數(shù)據(jù)集還有一個名為FilterGroup的屬性,它是一個基于記錄狀態(tài)的過濾器。為了防止使用FilterGroup時移動記錄指針,采用復制的方法來判斷是否有修改過的記錄:Function ADOUpdatesPending(ADODataSet :TCustomADODataSet):BooleanVarClone:TADODataSet;Beg
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 總經(jīng)理助理轉(zhuǎn)正工作總結(jié)8篇
- 數(shù)學教學工作總結(jié)(匯編15篇)
- 小學生讀書演講稿4篇
- 2017年寒假綜合實踐作業(yè)總結(jié)
- 將精神撫慰金列入刑事附帶民事訴訟
- 做幸福教師演講稿(4篇)
- 2025年文旅小鎮(zhèn)合作協(xié)議書
- 停車場地出租合同(2篇)
- 2025年CBZ-5-苯基-L-半胱氨酸項目發(fā)展計劃
- 個人車輛出租合同
- 關(guān)于大數(shù)據(jù)的職業(yè)生涯規(guī)劃書課件
- 部編版高中語文必修上冊第二單元測試題及答案
- 電子化文件與信息管理制度
- 2024年高考地理試卷(浙江)(1月)(解析卷)
- 心理健康講座(課件)-小學生心理健康
- 《腸造口并發(fā)癥的分型與分級標準(2023版)》解讀
- 名畫中的瘟疫史智慧樹知到期末考試答案章節(jié)答案2024年上海健康醫(yī)學院
- 《跟上兔子》繪本三年級第1季One-Day教學課件
- 家長會課件:小學三年級家長會 課件
- 孕產(chǎn)婦妊娠風險評估表
- PDCA循環(huán)培訓課件
評論
0/150
提交評論