分享
 
 
 

多层数据库开发五:连接数据库

王朝delphi·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

第五章 连接数据库

在数据库应用程序中,TDatabase构件是很有用的。它能够管理和操纵数据库的连接,控制数据库连接的持续性。TDatabase构件还提供了管理事务和申请更新数据的功能。

第三章已经详细介绍了TSession与TDatabase的关系,所有的数据库连接都在TDatabase构件的控制之下,而所有的TDatabase构件又在BDE会话期对象的管理之下。

5.1 永久和临时的TDatabase构件

很多情况下,其实并没有必要显式地使用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

Begin

With FindSession(SessionName) Do

Result := FindDatabase(DatabaseName);

If Result = nil then

Begin

TempDatabase := TDatabase.Create(Self);

TempDatabase.DatabaseName := DatabaseName;

TempDatabase.SessionName := SessionName;

TempDatabase.KeepConnection := True;

End;

Result := OpenDatabase(DatabaseName);

End;

Except

TempDatabase.Free;

Raise;

End;

End;

可以这样调用RunTimeDbCreate函数:

var

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

MyDbCount: Integer;

Begin

MyDbCount := 1;

...

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

Inc(MyDbCount);

...

End;

5.2 控 制 连 接

无论是永久的TDatabase构件还是临时的TDatabase构件,都可以通过它们的属性、方法和事件来控制有关连接数据库的行为,这也是使用TDatabase构件的主要目的。

5.2.1 指定一个BDE会话期

所有的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;

5.2.3 设置BDE别名的参数

要设置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

Begin

Params.Clear;

Params.Add('UserName = Sysdba');

Params.Add('Password = 1234');

LoginPrompt := False;

Open;

End;

5.2.4 登录到服务器

大多数服务器都有严密的安全措施,以防止未授权的访问。对于用户来说,他面临的第一道关卡就是登录,即输入用户名和口令。

在设计期,当试图连接一个远程服务器时,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属性。

5.2.5 开始连接数据库服务器

要开始连接数据库服务器,可以调用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函数总是能断开连接。

5.2.6 网络协议和ODBC

Delphi 4用BDE和SQL Links驱动程序来连接数据库服务器,其中,BDE还可以驱动ODBC访问更广泛的数据源。

在配置SQL Links和ODBC驱动程序时要注意网络协议的问题。大部分情况下,网络协议由数据库服务器的客户端软件来配置,但对于ODBC来说,还需要在专门的ODBC管理程序中配置网络协议。

刚开始连接服务器时往往很难成功,这时候首先要检查客户端软件是否正确配置,如果使用TCP/IP协议的话,要检查是否安装了支持TCP/IP协议的软件如WINSOCK.DLL,服务器的IP地址是否在客户端的HOSTS文件中注册,域名服务是否正确配置。

5.3 遍历一个数据库的所有数据集

TDatabase构件的DataSets属性和DataSetCount属性配合起来使用可以遍历一个数据库的所有数据集。

DataSets属性是一个数组,它的每一个元素是一个活动的数据集如TTable、TQuery或TStoredProc,每个数据集都可以通过序号来访问。

DataSetCount属性返回DataSets数组中元素的个数,程序示例如下:

var

I: Integer;

Begin

For I := 0 to DataSetCount - 1 Do

If DataSets[I] is TTable then

DataSets[I].CachedUpdates := True;

End;

5.4 TDatabase与TSession的关系

TDatabase构件主要用于管理数据库的连接,而TSession则用于对一个应用程序中的TDatabase构件进行全局控制,包括临时的TDatabase构件。

TSession的方法往往是针对所有的TDatabase构件的,它不考虑TDatabase构件的状态。例如,TSession的DropConnections函数将关闭所有的数据集,并断开所有的数据库,即使这些TDatabase构件的KeepConnections属性设为True。

而TDatabase只能管理它所连接的数据库,例如,TDatabase的CloseDataSets函数只关闭某个数据库的所有数据集,不关闭其他数据库的数据集。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有