天天看點

多層資料庫開發五:連接配接資料庫

                                                   第五章 連接配接資料庫

  在資料庫應用程式中,TDatabase構件是很有用的。它能夠管理和操縱資料庫的連接配接,控制資料庫連接配接的持續性。TDatabase構件還提供了管理事務和申請更新資料的功能。

  第三章已經詳細介紹了TSession與TDatabase的關系,所有的資料庫連接配接都在TDatabase構件的控制之下,而所有的TDatabase構件又在BDE會話期對象的管理之下。

<b>5.1 永久和臨時的TDatabase構件</b>

  很多情況下,其實并沒有必要顯式地使用TDatabase 構件。當應用程式試圖打開一個資料庫時,會自動建立一個臨時的TDatabase構件。當然,這個臨時的TDatabase 構件隻在資料庫連接配接期間是有效的,一旦關閉了資料庫,這個臨時的TDatabase 構件将被删除。

  不過,在有的資料庫應用程式尤其是兩層或多層的Client/Server應用程式中,最好還是顯式地使用TDatabase構件。凡是在設計期加到窗體或資料子產品上的TDatabase構件,我們稱為永久的TDatabase構件,這是相對臨時的TDatabase構件而言的。

  使用永久的TDatabase構件的好處是,可以建立永久的連接配接,具有管理事務的能力,可以建立應用程式專用的BDE别名,還可以響應OnLogin事件。

  臨時的TDatabase構件的功能就有某種程度的局限,它的有些關鍵屬性受制于它所屬的BDE會話期對象,例如,BDE會話期對象的KeepConnections屬性決定了當所有資料集都關閉後資料庫是否繼續維持在連接配接狀态。而永久的TDatabase構件的KeepConnections 屬性則不受BDE會話期對象的KeepConnections屬性的影響。

  有時候,往往很難确定到底需要用幾個TDatabase構件,而您又不希望用臨時的TDatabase構件來代替,這時候,就需要在運作期動态地建立TDatabase構件。

  要在運作期動态地建立TDatabase構件,首先要聲明一個TDatabase類型的變量,然後調用TDatabase的Create函數來建立TDatabase的對象執行個體。程式示例如下:

Function RunTimeDbCreate(const DatabaseName, SessionName: string): TDatabase;

var

TempDatabase: TDatabase;

Begin

TempDatabase := nil;

Try

Sessions.OpenSession(SessionName);

With Sessions Do

With FindSession(SessionName) Do

Result := FindDatabase(DatabaseName);

If Result = nil then

TempDatabase := TDatabase.Create(Self);

TempDatabase.DatabaseName := DatabaseName;

TempDatabase.SessionName := SessionName;

TempDatabase.KeepConnection := True;

End;

Result := OpenDatabase(DatabaseName);

Except

TempDatabase.Free;

Raise;

  可以這樣調用RunTimeDbCreate函數:

MyDatabase: array [1..10] of TDatabase;

MyDbCount: Integer;

MyDbCount := 1;

...

MyDatabase[MyDbCount]:=RunTimeDbCreate('MyDb'+IntToStr(MyDbCount),'');

Inc(MyDbCount);

<b>5.2 控 制 連 接</b>

  無論是永久的TDatabase構件還是臨時的TDatabase構件,都可以通過它們的屬性、方法和事件來控制有關連接配接資料庫的行為,這也是使用TDatabase構件的主要目的。

<b>5.2.1 指定一個BDE會話期</b>

  所有的TDatabase構件都必須指定一個它所屬的BDE會話期,這就要用到兩個屬性,一個是SessionName,另一個是Session。

  SessionName屬性用于指定一個BDE會話期的名稱。當在設計期把一個TDatabase構件放到窗體或資料子產品上時,它的SessionName屬性自動設為“Default”,這是預設的BDE會話期的名稱。如果您已經在窗體或資料子產品上放了若幹個TSession構件,您就可以從一個下拉清單中選擇SessionName屬性的值。

  Session屬性是隻讀的,用于傳回TDatabase構件所屬的BDE會話期對象。如果SessionName屬性設為空或“Default”,Session屬性就傳回預設的BDE會話期對象。

  通過Session屬性傳回BDE會話期對象後,您就可以通路TSession的屬性、方法和事件,即使您不知道該BDE會話期對象的實際名稱。

5.2.2 指定要通路的資料庫

  要指定一個資料庫,就要用到AliasName屬性或DriverName屬性。這兩個屬性是互斥的,設定其中一個,另一個就被清空。修改AliasName、DriverName、DatabaseName等屬性之前都要先把Connected屬性設為False,否則将觸發異常。

  AliasName屬性用于指定一個資料庫的别名,隻能設為已有的BDE别名如DBDEMOS、DefaultDB、IBLOCAL等。

  資料庫的别名一般是用SQL Explorer或BDE管理程式定義的。不過,也可以用DatabaseName屬性定義一個應用程式專用的别名。DatabaseName屬性可以設為一個已有的BDE别名。對于Paradox和dBASE表來說,也可以設為表所在的路徑。

  用DatabaseName屬性定義的别名隻限于在本應用程式中使用,它将出現在TTable、TQuery、TStoredProc構件的DatabaseName屬性的下拉清單中。

  DriverName屬性用于指定一個資料庫驅動程式的類型,可以設為STANDARD(用于dBASE和Paradox)、MSSQL、INTERBASE、ORACLE、SYBASE、INFormIX等。設定了DriverName屬性後,還得設定Params屬性指定連接配接參數。

  資料庫驅動程式其實是BDE别名的一個參數。是以,設定了AliasName屬性後,DriverName就會自動清空。反之,設定了DriverName 屬性後,AliasName屬性也會自動清空,否則就會出現沖突。這樣看來,DriverName屬性似乎作用不大,隻要設定AliasName屬性就夠了。不過,當DatabaseName屬性定義一個應用程式專用的别名時,需要設定DriverName屬性指定該别名使用什麼驅動程式。

  在設計期,要指定一個BDE别名或者資料庫驅動程式或者定義一個專用的别名,既可以在對象觀察器中進行,也可以輕按兩下TDatabase構件打開資料庫屬性編輯器,然後在“Name”框内設定DatabaseName屬性的值,在“Alias Name”框内設定Alias屬性的值,在“Driver Name”框内設定DriverName屬性的值。

  也可以在運作期設定DatabaseName、AliasName或DriverName屬性的值,例如:

  Database1.DatabaseName := Edit1.Text;

<b>5.2.3 設定BDE别名的參數</b>

  要設定BDE别名的參數,如路徑、伺服器名、緩存長度、語言驅動程式、使用者名、密碼等,就要用到Params屬性。

  在設計期,要設定BDE别名的參數有三種方式:

  一是使用SQL Explorer或BDE Administrator來定義或修改别名以及參數。

  二是在對象觀察器中單擊Params屬性邊上的省略号按鈕打開字元串清單編輯器,然後按格式鍵入參數的名稱和值。

  三是輕按兩下TDatabase構件打開資料庫屬性編輯器,如圖5.1所示。

  圖5.1 設定BDE别名的參數

  單擊“Defaults”按鈕将在“Parameter Overrides”框内列出與驅動程式所對應的預設參數,對于dBASE和Paradox來說,預設的參數主要是路徑,對于遠端伺服器來說,預設的參數就多了,包括伺服器名、使用者名和密碼、語言驅動程式等。

  單擊“Clear”按鈕可以把“Parameter Overrides”框實際上就是Params屬性清空。

  可以直接在“Parameter Overrides”框内修改參數,也可以添加新的參數。

  要在運作期設定BDE别名的參數,就要用到TStrings對象。從圖5.1也可以看出,Params屬性實際上是一個字元串清單,每個字元串的格式是“名稱=值”。程式示例如下:

With Database1 Do

Params.Clear;

Params.Add('UserName = Sysdba');

Params.Add('Password = 1234');

LoginPrompt := False;

Open;

<b>5.2.4 登入到伺服器</b>

  大多數伺服器都有嚴密的安全措施,以防止未授權的通路。對于使用者來說,他面臨的第一道關卡就是登入,即輸入使用者名和密碼。

  在設計期,當試圖連接配接一個遠端伺服器時,Delphi 4會推出一個标準的登入對話框,讓您輸入使用者名和密碼。

  在運作期,有三種方式進行登入:

  第一種方式是把LoginPrompt屬性設為True,這樣,當需要連接配接遠端伺服器時,就會自動彈出一個标準的登入對話框,讓使用者輸入使用者名和密碼。

  第二種方式是把LoginPrompt屬性設為False,并且設定Params屬性,其中應包含“USER NAME”和“PASSWORD”參數,例如:

  USER NAME=SYSDBAPASSWORD=masterkey

  注意:在程式中通過代碼提供使用者名和密碼容易洩密,建議最好不要用這種方式。

  第三種方式就是在處理OnLogin事件的句柄中設定LoginParams參數,程式示例如下:

  LoginParams.Values['USER NAME'] := UserName;

  LoginParams.Values['PASSWORD'] := PasswordSearch(UserName);

  當退出處理OnLogin事件的句柄時,LoginParams參數的值就被賦給Params屬性。

<b>5.2.5 開始連接配接資料庫伺服器</b>

  要開始連接配接資料庫伺服器,可以調用Open函數或者把Connected屬性設為True。實際上,把Connected屬性設為True會自動調用Open。此時,會觸發OnLogin事件。如果程式沒有處理OnLogin事件,就會彈出一個标準的登入對話框讓使用者登入。

  如果在沒有連接配接伺服器的情況下試圖打開一個資料集,将首先調用Open函數連接配接伺服器,并根據需要自動建立一個臨時的TDatabase構件。

  一旦與伺服器建立了連接配接,隻要至少有一個資料集是活動的,連接配接就會一直保持。如果所有的資料集都不處于活動狀态,是否斷開連接配接取決于KeepConnections屬性的值。

  如果KeepConnections屬性設為True,即使沒有一個資料集處于活動狀态,也保持連接配接,對于那些頻繁地打開和關閉資料集的應用程式來說,可以避免老是登入。如果KeepConnections屬性設為False,當所有的資料集都關閉了時,将斷開與伺服器的連接配接。

  要斷開連接配接,就要調用Close或者把Connected屬性設為False。實際上,把Connected屬性設為False會自動調用Close。

  Close會自動關閉所有的資料集,然後斷開連接配接。如果隻想關閉所有的資料集,但不想斷開連接配接,首先要把KeepConnections屬性設為True,然後調用CloseDataSets函數。

  注意:即使KeepConnections屬性設為True,調用Close函數總是能斷開連接配接。

<b>5.2.6 網絡協定和ODBC</b>

  Delphi 4用BDE和SQL Links驅動程式來連接配接資料庫伺服器,其中,BDE還可以驅動ODBC通路更廣泛的資料源。

  在配置SQL Links和ODBC驅動程式時要注意網絡協定的問題。大部分情況下,網絡協定由資料庫伺服器的用戶端軟體來配置,但對于ODBC來說,還需要在專門的ODBC管理程式中配置網絡協定。

  剛開始連接配接伺服器時往往很難成功,這時候首先要檢查用戶端軟體是否正确配置,如果使用TCP/IP協定的話,要檢查是否安裝了支援TCP/IP協定的軟體如WINSOCK.DLL,伺服器的IP位址是否在用戶端的HOSTS檔案中注冊,域名服務是否正确配置。

<b>5.3 周遊一個資料庫的所有資料集</b>

  TDatabase構件的DataSets屬性和DataSetCount屬性配合起來使用可以周遊一個資料庫的所有資料集。

  DataSets屬性是一個數組,它的每一個元素是一個活動的資料集如TTable、TQuery或TStoredProc,每個資料集都可以通過序号來通路。

  DataSetCount屬性傳回DataSets數組中元素的個數,程式示例如下:

I: Integer;

For I := 0 to DataSetCount - 1 Do

If DataSets[I] is TTable then

DataSets[I].CachedUpdates := True;

<b>5.4 TDatabase與TSession的關系</b>

  TDatabase構件主要用于管理資料庫的連接配接,而TSession則用于對一個應用程式中的TDatabase構件進行全局控制,包括臨時的TDatabase構件。

  TSession的方法往往是針對所有的TDatabase構件的,它不考慮TDatabase構件的狀态。例如,TSession的DropConnections函數将關閉所有的資料集,并斷開所有的資料庫,即使這些TDatabase構件的KeepConnections屬性設為True。

  而TDatabase隻能管理它所連接配接的資料庫,例如,TDatabase的CloseDataSets函數隻關閉某個資料庫的所有資料集,不關閉其他資料庫的資料集。