Delphi 2006高效数据库程序设计——dbExpress篇(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-08 10:24:22

点击下载

作者:李维

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Delphi 2006高效数据库程序设计——dbExpress篇

Delphi 2006高效数据库程序设计——dbExpress篇试读:

新版序

当笔者决定更新本书时,很难相信从Delphi 7到Delphi 2006已经过了将近4年的时间。在这段时间中,Borland的数据库访问技术也有了相当大的变化。首先让我们介绍本书的主题:dbExpress。dbExpress从Delphi 7的2.0版本发展到了Delphi 2006的3.0版,其中的变化除了更新对于各种数据库最新版本的支持之外,更重要的进步就在于执行效率不断地提升以及在Win32、Linux和.NET环境中能够同时执行。在Borland宣布未来将推出Win64的Delphi版本之后,我们也可以预料到未来dbExpress也将会有64位的版本。除了这些之外,dbExpress也有许多其他的进步。例如dbExpress开始加入支持MSSQL Unicode的能力,也可以处理返回结果数据集的存储过程,强化MetaData的支持能力,更高的执行存储过程效率,等等。简而言之,dbExpress现在已经进化成Delphi中最重要的数据库访问技术了(见表0-1)。表0-1

除了dbExpress之外,Borland在.NET下基于ADO.NET的数据库访问技术Borland Data Provider(BDP),也有着显著的进步。BDP也和dbExpress一样,执行效率不断地提升。

Delphi 2006的BDP加入了连接池的功能,让BDP在连接、访问和服务大量客户端的情形下的执行效率比以前的版本增加了数倍(见表0-2)。表0-2

从dbExpress和BDP的进步幅度来看,Delphi R&D团队对于Delphi中数据库访问技术的承诺是相当保守的,Delphi R&D团队决心在Win32/.NET环境中提供最好的数据库访问技术,当然,未来dbExpress和BDP也都会推出64位的版本。

本书的目标是希望帮助想使用Delphi 2006开发数据库应用程序但是对于dbExpress技术并不熟悉的开发人员,使他们能够快速掌握dbExpress,进而熟练地使用dbExpress来开发数据库应用程序。本书除了更新《Delphi 7高效率数据库程序设计》一书的内容之外,也加入了从dbExpress 2.0之后许多新的功能,此外,也讨论了如何在.NET执行环境中使用dbExpress。这是因为Borland已经把整个VCL架构,包括了dbExpress相关的类,都移植到了.NET上,因此,dbExpress应用程序只需要使用Delphi.NET编译器重新编译就可以成为在.NET中执行的应用程序。当然,在讨论的过程中,本书也会讨论其中的原理并且也会比较Delphi在.NET环境下的BDP技术,让您不但知道如何使用dbExpress,也能够掌握其中设计和实现的原理,并且能够对.NET下Delphi提供的dbExpress和BDP 2大数据库访问技术有深入的了解。《Delphi 2006高效数据库程序设计——dbExpress篇》在《Delphi 7高效数据库程序设计》的基础上,以Delphi 2006更新了内容,并且对下面的篇幅作了较大的更新:

■ 第2章,调用MS SQL Server返回结果数据集的存储过程2.4.1小节■ 第3章,增加dbExpress 3.0和DBE 5.x版执行效率的比较

■ 第5章,如何使用MyBase

■ 第5章,更新dbExpress和COM+使用的内容

■ 第7章,各种不同的Web开发方式

■ 第7章,Delphi Web 加上IntraWeb的内容

■ 第9章,增加Metadata的讨论以及Metadata对于应用程序执行效率的影响■ 第9章,增加使用Delphi 2006封装的dbExpress接口类

■ 第13章,增加未来dbExpress实现的方向讨论■ 第14章,增加Delphi.NET中dbExpress的使用李 维2006年3月于台北,新店

旧版序

自从Delphi推出以来,Delphi全方位的功能便让许多程序员津津乐道。而Delphi在数据库方面提供的强大而富有弹性的能力更是让许多数据库程序员惊喜不已。Delphi 的BDE/IDAPI不但提供了合理的执行效率,而且能够连接各种不同的数据库。从File-Based的Paradox/dBase数据库到真正的关系数据库如InterBase、Oracle、Informix、DB2和MS SQL Server等,都能够让Delphi的程序员使用相同的技术来访问各种不同的数据源,实在是非常的方便。

但是随着软件技术的进步以及用户需求的变化,数据访问的方法也随之出现巨大的改变。从以往提供持续连接的主从架构应用系统转换成现在的以批处理,而且客户端和数据库之间可能是处于没有连接的状态。例如现在的数据访问技术必须同时能够满足在企业内部的主从架构式应用系统,以及能够提供Web访问的分布式应用系统。虽然BDE/IDAPI技术也可以同时使用在这两种应用之中,但是BDE/IDAPI毕竟是以File-Base和主从架构观念设计的,对于 Web-Based 和分布式架构的应用无法提供比较有效率和经济的使用方法。

Borland为了解决用户新的需求以及提供Borland开发工具用户跨平台的能力,以响应Borland推出执行在Linux上的开发工具-Kylix,因此,Borland必须认真地考虑开发下一代的数据访问技术,因为 BDE/IDAPI 明显已经无法满足新的应用而且无法提供跨平台的功能。这些原因促使了dbExpress的诞生。

dbExpress是Borland下一代的数据访问技术。dbExpress的设计目标是提供高效数据访问以及提供跨平台能力的数据访问引擎。自从Delphi 6之中Borland推出了dbExpress 1.0

之后,dbExpress发展得相当迅速。目前dbExpress已经能够访问许多的关系数据库,包括Oracle,InterBase,Informix,DB2,MS SQL Server,MySQL,PostgreSQL等,而且在未来Borland 将持续地开发Sybase等数据库的dbExpress驱动程序。此外,目前dbExpress已经能够在Windows和Linux平台上运行,未来也将移植到Microsoft的.NET上运行。

Delphi 7之中的dbExpress已经是2.0的版本了。在dbExpress 2.0中不但提供了更多的 dbExpress 驱动程序,修改了许多的臭虫,还提供了更高的执行效率。由于 dbExpress现在的表现已经超越BDE/IDAPI,而且Borland也已经宣布BDE/IDAPI将不再更新,只是提供基本的维护。因此Delphi/Kylix/C++Builder的程序员也必须使用dbExpress来开发新的数据库应用程序。

遗憾的是,虽然dbExpress提供了良好的功能和效率,但是目前市面上几乎没有什么书籍专门讨论 dbExpress 技术,以便帮助程序员善加利用 dbExpress 的功能以开发高效率的数据库应用系统。就是由于这个原因而促使笔者撰写本书,希望借助本书的内容能够帮助读者彻底掌握 dbExpress 技术。本书除了讨论如何使用 dbExpress 以及 Delphi/Kylix 的DataSnap技术之外,更详细而且深入地讨论了dbExpress的高级技术。其中包含了如何调整dbExpress的执行效率,dbExpress的实现原理以及dbExpress未来的发展,以便让读者能够充分地发挥dbExpress引擎的强大功能,开发出高效率的Delphi/Kylix数据库应用系统。

笔者从Delphi 6.0/Kylix 1.0开始撰写本书,虽然Delphi 7的dbExpress和DataSnap有少许的改善,不过本书的内容仍然适用于Delphi 6/Kylix 2.0以及Delphi 7/Kylix 3.0,此外笔者也在书中说明了Delphi 6和Delphi 7的不同之处。

笔者要谢谢所有帮助本书出版的朋友,更要谢谢读者的支持。最后希望本书的内容真的能够帮助读者快速进入 dbExpress 的世界,并且在阅读完毕之后成为精通 Delphi/Kylix数据库应用系统设计的高手,谢谢!李维2002年10月于台北,新店

第1部分 dbExpress基本功能篇

第1章 dbExpress控件,概念,技术和应用程序

Delphi 6/7的重要功能之一便是推出了新一代的跨平台的数据存取引擎:dbExpress。dbExpress是一组新的控件、技术和驱动程序,以允许开发人员使用它连接到各种数据源,再配合连接不同数据库的DLL文件,让开发人员处理后端数据库中的数据。由于dbExpress具备了跨平台的能力,能够使用在Windows和Linux平台以及未来的.NET上,而且提供了快速的数据处理能力,让开发人员开发出更有效率的数据库应用程序,因此,势必成为以后C++Builder/Delphi和Kylix的核心数据存取技术。在Delphi 2006中更进一步地把dbExpress升级到3.0的版本,除了增加支持更多、更新的关系数据库之外,dbExpress 3.0也大幅增加了执行效率,开始支持Unicode,更重要的是dbExpress 3.0也移植到了.NET执行环境中,让dbExpress应用程序能够同时执行在Win32、Kylix、.NET以及未来的Win64作业环境里。此外,在本书稍后的章节中读者也会发现,Borland正努力让dbExpress以及.NET下的BDP数据存取一致化,因此,dbExpress和BDP存在许多类似的服务,这样做的好处是让开发人员能够以最小的成本掌握两种数据存取技术,也让应用程序之间的移植工作更为简单。

这些新的dbExpress控件除了刚进入Delphi世界的开发人员需要学习之外,即使是已经使用Delphi有一段时间并有经验的Delphi开发人员也需要上手的时间。此外,dbExpress提供了强大的功能,允许Delphi开发人员微调它的执行行为,并且存取底层的核心信息。同时dbExpress也能够和旧的Delphi版本中称为MIDAS的技术一起工作,而与Delphi 6/7中称为DataSnap的技术结合可以让开发人员能够同时开发单机、Briefcase、客户/服务器和Thin-Client类型的数据库应用程序,让开发人员能够使用一组控件和技术同时开发数种类型的应用系统。到了Delphi 2006,dbExpress更允许Delphi的开发人员能够移植到.NET执行环境中,在.NET环境下也能够开发出以往Win32下各种类型的dbExpress应用系统。

我们将会在本书中介绍所有dbExpress强劲的功能。万丈高楼平地起,本章将从说明如何使用这些新的dbExpress控件开始,一步一步地带领各位学习到dbExpress最精髓的核心技术。1.1 dbExpress控件

dbExpress控件集在Delphi 7中包含了7个控件,这些控件的功能就是让应用程序连接后端数据库,访问数据表中的数据,把变更的数据更新回数据库之中以及让开发人员观察dbExpress向后端数据库下达的命令等。简单地说,这些控件涵盖了数据库应用程序所有必要的功能。图1-1是dbExpress控件集中的所有dbExpress控件。图1-1 Delphi 2006的dbExpress控件集

表1-1概要地说明了每一个dbExpress控件基本的功能,在稍后的章节中将会详细介绍每一个dbExpress控件是如何使用的。表1-1

dbExpress控件还可搭配Delphi 2006中Data Access控件集中的TClientDataSet、TDataSetProvider等控件开发单层、客户/服务器以及多层架构的数据库应用程序,本书稍后都会详细地说明。

在Delphi 2006/C++Builder 2006中,dbExpress目前正式支持6种数据库,这些支持的数据库以及dbExpress相对应的驱动程序如表1-2所示。表1-2

Delphi 2006的dbExpress 3.0不但支持了更新的关系数据库,而且比dbExpress 1.x/2.x版增加了Adaptive Sybase Anywhere以及Sybase的支持,此外,目前dbExpress对于MySQL的支持虽然只到4.0.24,但是Borland准备在不久的将来也支持最新的MySQL 5.0。

要学习dbExpress控件最好的方法就是直接使用它来开发数据库应用程序,在下一节我们将立刻进入学习dbExpress控件集的世界之中,让开发人员快速地学习如何使用这些新的控件开发应用系统。1.2 建立第一个dbExpress数据库应用程序

现在就让我们快速地使用dbExpress来开发一个数据库应用程序,学习如何使用dbExpress控件来存取数据。要连接数据库并且从其中存取数据,开发人员可以使用以下三个步骤来完成这项工作:

1.使用TSQLConnection控件连接数据库;

2.使用TSQLDataSet控件存取数据;

3.显示数据在数据感知控件之中。

现在就让我们一步一步地来完成上面的三个步骤。

步骤1 使用TSQLConnection控件连接数据库

首先点击Delphi的File|New|VCL Forms Application-Delphi For Win32菜单建立一个新的Delphi项目,接着点击控件集中的dbExpress页签,选择第一个控件TSQLConnection,并且放入应用程序的主窗体,如图1-2所示。有了TSQLConnection控件之后,现在我们要让它连接到数据库服务器,在这个范例中是使用InterBase,读者也可以使用其他数据库,例如Oracle或是MySQL等。图1-2 在主窗体中放入TSQLConnection控件以连接数据库

要使用TSQLConnection连接数据库,请使用鼠标双击TSQLConnection,此时会出现TSQLConnection的控件编辑器,如图1-3所示。在图1-3中列出了目前dbExpress内定的连接或是用户新增的连接,由于现在本范例要使用InterBase作为连接的数据库,因此,请使用鼠标点击上方的【+】按钮以建立一个新的连接。图1-3 TSQLConnection控件的控件编辑器

此时,Delphi会显示图1-4所示的新连接对话框,请在这个对话框中选择使用InterBase驱动程序,并且输入一个连接名称。在这个范例中使用了CHINESEDEMO作为本范例的连接名称。图1-4 dbExpress的新数据库连接对话框

接着Delphi会显示图1-5所示的对话框,要求输入CHINESEDEMO真正的数据库路径和名称信息,请如图 1-5 般输入数据库的物理位置。由于 CHINESEDEMO 使用的InterBase数据库是使用GB_2312编码建立的,因此,请读者记住改变ServerCharSet的属性值为GB_2312。在输入了数据库物理位置之后,读者可以点击对话框上方的【√】按钮,以测试是否可以正确连接到数据库。确定一切正确之后,最后点击【OK】按钮以完成设定TSQLConnection控件的步骤。[1]图1-5 输入CHINESEDEMO要连接的InterBase数据库

读者可以在本书的附属光盘中找到CHINESEDEMO.GDB这个InterBase数据库。

如果读者仔细观察图1-5中的对话框,便会发现刚才设定的CHINESEDEMO这个InterBase连接信息事实上是储存在\Borland\BDS\4.0\dbExpress目录下的dbxconnections.ini文件之中的,这是一个文本文件,读者也可以使用文字编辑器,例如NotePad或是Delphi的编辑器来修改其中的内容。

现在请点击对象查看器,设定TSQLConnection的LoginPrompt属性值为False,以避免出现登录对话框,最后再把Connected属性值设定为True。这样一来,我们就成功地连接到InterBase服务器了(当然,读者的InterBase服务器必须在运行中)。

步骤2 使用TSQLDataSet控件存取数据

现在再从dbExpress页签中选择第二个控件TSQLDataSet,并且放入主窗体中。先在对象查看器中设定它的SQLConnection属性值为步骤1放入的SQLConnection1,然后点击它的CommandText属性值。此时,Delphi便会显示CommandText属性的属性值编辑器,让开发人员使用可视化的方式下达SQL命令。图1-6便是启动CommandText属性值编辑器的画面。图1-6 TSQLDataSet的CommandText属性值编辑器

当CommandText属性值编辑器出现时,它会自动地从连接的数据库中取得所有目前可以被看到的数据表名称,放入到加左上方的Tables列表框中,而把选择的数据表的字段信息呈现在左下方的列表框中,真正的SQL命令则是在右边的Memo控件中。至于什么数据表会出现在左上方的Tables列表框中,则是由TSQLConnection的TableScope属性值来决定的。

由于CHINESEDEMO中只有一个数据表BIOLIFE,因此,请使用鼠标双击左上方的BIOLIFE,再双击左下方的[*]以代表要从BIOLIFE数据表中取得所有字段的数据,这样一来,CommandText属性值编辑器便会在右边的SQL窗口中自动产生select*from BIOLIFE的SQL命令,如图1-7所示。图1-7 使用CommandText属性值编辑器完成SQL命令

请点击【OK】按钮,Delphi便会把刚才完成的SQL命令储存在TSQLDataSet控件的CommandText属性值中。接着在主窗体中放入一个从Data Access控件种类中选择的TDataSource控件,设定它的DataSet属性值为刚才的TSQLDataSet控件,再放入一个TDBNavigator控件,设定它的DataSource属性值为刚放入的TDataSource控件。

现在我们就可以借助把TSQLDataSet的Active属性值设定为True,把数据从BIOLIFE数据表中取到应用程序中。接着启动TSQLDataSet的字段编辑器把代表BIOLIFE每一个字段的字段对象加入到应用程序中,这样做的好处是开发人员可以使用Delphi的对象查看器来设定字段对象的属性,例如字段显示的中文名称,或是设定字段显示的宽度等。

请点击主窗体中的TSQLDataSet控件,按下鼠标右键,Delphi会显示一个快捷菜单,菜单中的第一个选项[Fields Editor…]便可以启动字段编辑器,如图1-8所示。图1-8 启动TSQLDataSet的字段编辑器

请点击这个选项,Delphi便会显示一个空白窗口,然后在这个空白窗口中点击鼠标右键,Delphi便会显示一个快捷菜单,点击这个菜单中的[Add all fields]选项,以便把BIOLIFE数据表中代表每一个字段的字段对象加入到应用程序中,如图1-9所示。接着Delphi便会把所有的字段对象加入到刚才的空白窗口中,现在我们就可以点击这个窗口中的每一个字段对象,然后使用对象查看器来设定它们的属性值。图1-9 加入所有的字段对象

当我们在图1-9中把字段对象加入之后,Delphi便会在主窗体中自动声明这些字段对象:

我们可以看到dbExpress会根据数据表中字段的数据类型而使用dbExpress中相对的类声明,例如字段数据类型如果是char或是varchar,就以TStringField类型声明,而如果字段数据类型是BLOB的类型,就以TBlobField类型声明,稍后开发人员就可以直接借助这些变量来存取和操作字段数据。

现在我们希望应用程序在执行时是显示中文的字段名称,而不是数据表中字段的英文名称,那么,我们就可以点击图1-9中的每一个字段对象,然后在对象查看器中设定字段对象的DisplayLabel属性,接着输入这个字段的中文代表名称即可。例如图1-10便是设定SPECIES_NO这个字段的中文代表名称的画面。图1-10 使用对象查看器设定字段对象的属性值

在我们设定完毕每一个字段对象的DisplayLabel属性值之后,便可以选择所有的字段对象,然后把它拖曳到主窗体中,那么Delphi便会自动地在主窗体中产生能够适当显示每一个字段对象的数据感知控件,并且显示数据在这些数据感知控件之中。例如图1-11便是把图1-10中所有字段对象拖曳到主窗体之中后的画面。图1-11 拖曳所有字段对象到主窗体之中

现在我们已经完成了第一个使用dbExpress控件实现的范例数据库应用程序,请执行它,此时我们便可以看到类似图1-12的画面。dbExpress控件果然可以顺利地从InterBase中存取数据,并且显示在数据感知控件之中,就和Delphi原本的BDE/IDAPI控件一样方便。图1-12 范例应用程序执行的画面,请注意TDBNavigator中所有和变更数据有关的按钮都被暂停,代表应用程序无法变更数据

如果读者仔细观察图1-12的画面,便会发现图1-12中的TDBNavigator中所有和变更数据有关的按钮,例如代表修改数据的【▲】按钮和新增数据的【+】按钮,都被暂停使用。这意味着我们无法使用这个范例应用程序来变更BIOLIFE数据表中的数据,也代表由dbExpress控件开发的数据库应用程序在内定上是无法变更的。

现在如果读者点击往下一笔的按钮移动到随后的记录,接着再点击往前的按钮欲把目前的记录移动到前一笔时,此时范例应用程序便会显示如图1-13所示的错误信息。图1-13 点击TDBNavigator中的前一笔数据的按钮时,范例应用程序会发生错误

出现这个错误信息是由于dbExpress控件开发的应用程序只能向后走的单向Cursor,而无法再向前走回到前面的记录。

也许读者会觉得奇怪,既然dbExpress无法变更数据,也无法任意移动目前记录的位置,那么dbExpress不是一点用处都没有吗?如何才能用来开发实际的数据库应用程序呢?

当然不是,这是因为dbExpress使用了和以往BDE控件不一样的方式来设计,因此,如果读者是以使用BDE的概念来使用dbExpress便会觉得奇怪。事实上,dbExpress不但能够做到和BDE控件一样的功能,甚至比BDE还有更多的功能,在执行效率上也胜过BDE。在本书进一步介绍如何使用dbExpress变更数据之前,先让我们说明dbExpress控件的一些重要的概念,以及它的设计架构,这样读者应该会更清楚地了解dbExpress的设计原理,在稍后的章节中也能更好地掌握dbExpress。1.3 使用dbExpress的概念

dbExpress控件集中与存取数据有关的控件,例如TSQLDataSet、TSQLTable等都是从TDataSet类继承下来的,因此,它们提供了所有和TDataSet一样的功能,也可以和Delphi的数据感知控件使用在一起以开发数据库应用程序。图1-14显示了这些dbExpress控件的类架构图。图1-14 dbExpress的类架构图

虽然TSQLDataSet等控件是从TDataSet继承下来的,但是它们与其他从TDataSet继承下来的控件,例如TBDEDataSet等控件不同。不同的是借助这些dbExpress控件取得的结果数据集是只读的。也就是说,由这些控件存取到的数据是不能够修改的,而且由这些dbExpress控件取得的结果数据集,其存取数据的方式只能由前往后存取,而无法由后往前存取。另外值得注意的是,在Delphi 2006中TCustomSQLDataSet已经改为从TWideDataSet中继承下来,而不像Delphi 6/7/2005是从TDataSet继承下来的。这是因为Delphi 2006的数据集类群组为了准备支持Unicode,而加入了新的类TWideDataSet,所有其他TDataSet的派生类都改为从TWideDataSet继承。TWideDataSet类在原本的TDataSet类服务中加入了同样的服务方法,但是采用了WideString的版本,这样一来,数据集类群组就能够处理日后的Unicode了。不过由于TWideDataSet也是从TDataSet继承下来的,因此,这样的改变并不会影响原有数据集类群组的执行行为。

如果开发人员想要变更由这些dbExpress取得的数据,或是想要在结果数据集中以任意的方式移动目前记录的位置,那么开发人员可以使用两种方法来达成:

1.在应用程序中再搭配使用控件集 Data Access 页签中的 TDataSetProvider 和TClientDataSet控件;

2.使用dbExpress控件集中的TSimpleDataSet控件。

稍后本书将会介绍如何使用这两种方式,现在先让我们介绍如何使用同样位于控件集dbExpress页签中的TSimpleDataSet控件。

TSimpleDataSet控件是Delphi 2006用来简化开发人员借助dbExpress控件变更数据的控件。使用TSimpleDataSet控件略等于使用TSQLDataSet控件与TDataSetProvider控件,再加上TClientDataSet控件。TSimpleDataSet不但能够存取数据,更能让开发人员变更数据和移动目前记录的位置。

基本上,TSimpleDataSet控件是使用TSQLDataSet控件从后端数据源中取得数据,再借助内部的缓存机制(cache)管理数据,借助内部缓冲(buffering)区机制允许开发人员任意地移动目前所记录的位置,并在开发人员需要变更数据回数据源时,根据它内部维持的信息,自动帮助开发人员产生变更数据的SQL语句,再借助TSQLDataSet控件使用这些自动产生的SQL语句把变更数据更新回数据源之中。因此,TSimpleDataSet控件等于是帮助开发人员撰写了管理数据以及更新变更数据回数据源的程序代码,而无须开发人员自己撰写这些程序代码。

图1-15就是TSimpleDataSet控件的类架构图,从图中可以看到TSimpleDataSet是从包含缓存机制的TCustomClientDataSet控件继承下来的。图1-15 TSimpleDataSet的类架构图

当开发人员使用TSimpleDataSet时,无须再搭配使用TSQLConnection和TSQLDataSet,因为TSimpleDataSet自己会在内部建立暂时的TSQLConnection控件、TDataSetProvider控件以及一个TInternalSQLDataSet控件。TSimpleDataSet会使用内部建立的TSQLConnection连接至数据库,再使用内部建立的TInternalSQLDataSet和TDataSetProvider处理数据。由于TSimpleDataSet内部使用了TDataSetProvider

控件,因此提供了数据变更的能力,这样比使用前面的TSQLDataSet只提供数据查询的能力方便多了。

此外,虽然开发人员在Delphi 2006中是使用dbExpress控件存取和处理数据的,但在dbExpress控件之下,开发人员仍然必须拥有每一个特定数据库的dbExpress驱动程序才可以存取特定的数据库。当开发人员像图1-5那样使用TSQLConnection控件指定连接特定的数据库时,dbExpress便会加载与此数据库相关的dbExpress驱动程序以存取这个数据库。

如果dbExpress想存取到特定的数据库,那么加载的dbExpress驱动程序仍然需要调用特定数据库的客户端驱动程序,才能够真正地存取特定数据库。例如要使用dbExpress存取Oracle,那么除了要在dbExpress中存取Oracle的DBXORA30.DLL这个驱动程序之外,由于DBXORA30.DLL是直接调用Oracle的Oracle Call Interface(OCI),因此,还需要Oracle客户端的OCI.DLL,否则dbExpress无法存取Oracle数据库。

例如图1-16就是dbExpress在存取数据库时实际的架构。当dbExpress控件要存取Oracle时,就使用了刚才叙述的流程。例如dbExpress要存取InterBase时,就需要加载dbExpress中存取InterBase的DBXINT30.DLL驱动程序,以及InterBase客户端的引擎GDS32.DLL。图1-16 dbExpress存取各种不同关系数据库的架构图

前面已经介绍过,在dbExpress控件借助驱动程序取得了结果数据集之后,开发人员可以再使用TSimpleDataSet来变更结果数据集之中的数据,因为TSimpleDataSet包含了内部缓存的机制,可以自动帮助开发人员完成这些工作。如果我们再详细地介绍什么是TSimpleDataSet内部缓存的机制,那么答案就更清楚了,这个缓存的机制事实上就是以前Delphi版本中的MIDAS技术。Delphi 2006中的MIDAS已经是第7个版本了(Delphi 7中的MIDAS是第5个版本),从Delphi 6开始它重新被命名为DataSnap技术。Delphi 2006中的DataSnap已从以往定义为分布式应用系统架构技术转换为跨平台的标准数据存取技术。这个意思是说,MIDAS 7不但可以使用开发分布式应用系统,在Delphi 2006也成为开发客户/服务器以及单机应用程序的标准存取数据的技术,并且能够同时使用在Windows平台的Delphi 2006中以及.NET 1.1平台之中。因此,DataSnap已经成为Delphi的核心技术之一,所有的Delphi开发人员都必须了解并且熟练地掌握DataSnap的技术,当然,本书也会充分地说明如何善用DataSnap技术。

因此,在Delphi 2006中开发数据库应用程序的架构就如图1-17所示的一样,应用程序借助dbExpress存取到数据,再由DataSnap(MIDAS 7)来管理和变更数据。图1-17 dbExpress应用程序执行架构图

图1-18是更详细的架构图,Delphi 2006中的应用程序借助dbExpress控件存取数据,而dbExpress是使用SQL语句从数据源中取得数据,当数据源根据SQL语句执行的结果数据集并且回传给dbExpress控件之后,dbExpress控件会再把结果数据集交由DataSnap技术来管理,以便开发人员能够对结果数据集中的数据进行处理和变更。

从图1-18中我们也可以了解到,借助TSimpleDataSet取得的数据事实上就是由DataSnap在缓存内存中维护的数据。几乎所有借助TSimpleDataSet的方法或是属性值处理的数据都是储存在这些缓存内存中的数据,只有当开发人员真正需要把缓存内存中的数据更新回数据源时,DataSnap才会借助SQL语句把经过变更的数据更新回数据库中,在稍后的章节中会说明如何变更数据并且把数据真正地更新回数据源中。图1-18 dbExpress应用程序执行详细架构图1.4 使用dbExpress变更数据

现在我们已经介绍了dbExpress的架构和原理,接下来将详细介绍dbExpress技术的精髓,让开发人员能够精确地掌握dbExpress技术。不过在学习dbExpress的其他功能之前,先让我们以实际的范例来说明是如何使用dbExpress任意移动记录位置和变更数据的。

本节也将同时介绍如何使用TSimpleDataSet,以及使用TSQLDataSet搭配TDataSetProvider和TClientDataSet控件,以便证明在前面章节中提到的变更数据的方式。首先让我们延续前面1.2节的范例来说明如何完整地处理CHINESEDEMO中BIOLIFE数据表的数据。第1步是让1.2节中使用的范例程序搭配TDataSetProvider和TClientDataSet控件。1.4.1 使用TSQLDataSet搭配TDataSetProvider和TClientDataSet控件

请回到Delphi 2006集成开发环境,打开前面的范例应用程序的主窗体,然后在主窗体中加入控件集Data Access页签中的TDataSetProvider和TClientDataSet控件,此时范例主窗体的画面如图1-19所示。

在前一节中已经说明了由dbExpress取得的结果数据集虽然无法修改,但是只要搭配Delphi的DataSnap技术就能够允许应用程序变更其中的数据。因此,现在我们要做的就是在范例应用程序中加入DataSnap的功能。图1-19 在范例主窗体中加入TDataSetProvider以及TClientDataSet控件

在加入了TDataSetProvider控件之后,使用对象查看器设定它的DataSet属性值为主窗体中原先的TSQLDataSet控件,如图1-20所示。图1-20 设定TDataSetProvider控件的DataSet属性值

TDataSetProvider控件能够把属于TDataSet类的控件,例如TSQLDataSet(请参考图1-14的类架构图),输出给TClientDataSet控件,以便让TClientDataSet控件能够管理输出TDataSet控件之中的结果数据集数据。

接着使用对象查看器设定刚才加入的TClientDataSet控件的ProviderName属性值为主窗体中的TDataSetProvider控件,如图1-21所示。图1-21 设定TClientDataSet控件的ProviderName属性值

现在TClientDataSet控件便可以管理由TDataSetProvider输出的数据,而TDataSetProvider输出的数据就是它连接的TSQLDataSet从后端数据源中取得的结果数据集。

最后把主窗体中的TDataSource控件的DataSet属性值从原先的TSQLDataSet改为刚才加入的TClientDataSet控件,再把TClientDataSet控件的Active属性值设定为True,这样一来,TClientDataSet便从TDataSetProvider取得数据,并且显示在主窗体的数据感知控件之中。

现在执行这个范例应用程序,读者就会看到类似图1-22所示的画面,从图中我们可以看到在使用了TDataSetProvider和TClientDataSet之后,范例应用程序便可以使用TDBNavigator任意地移动目前的记录,也不会出现错误了。因此,使用DataSnap技术之后,dbExpress单向Cursor的限制就已经被克服了。

此外,TDBNavigator中的新增、修改和删除按钮似乎也可以工作,而不像图1-12中一样被暂停使用。读者可以先在范例应用程序中试着修改或删除数据,然后点击【√】按钮把数据更新回去。这样做似乎是正确的,但是如果读者结束范例应用程序,然后再次执行范例应用程序,会发现原先修改或删除的数据又出现在范例应用程序中,这代表刚才修改和删除的操作并没有真正对数据发生作用,这是为什么呢?图1-22 执行修改过的范例程序

这是因为在使用DataSnap的应用程序中,当应用程序变更数据并且调用TClientDataSet的Post方法或是点击TDBNavigator【√】按钮更新数据时,只是把数据更新回图1-18中由DataSnap管理的缓存内存中,而数据并没有真正更新回后端数据源之中。要真正把变更的数据更新回数据源中,开发人员必须再调用TClientDataSet的ApplyUpdates方法。

TClientDataSet的ApplyUpdates方法会把图1-18中由DataSnap管理的缓存内存中所有已经被变更的数据,包含新增、修改和删除的数据,一起更新回后端数据源中。TClientDataSet事实上是借助它连接的TDataSetProvider控件自动产生SQL语句帮助开发人员更新数据的,在稍后的章节中会详细介绍这个流程。下面是ApplyUpdates方法的声明原型:

ApplyUpdates 方法接受一个整数类型的参数:MaxErrors。MaxErrors 代表当TDataSetProvider自动更新数据时,开发人员所允许发生的错误次数。我们已经说明了当调用ApplyUpdates方法时,DataSnap会将所有在缓存内存中自上次调用ApplyUpdates方法之后到本次调用ApplyUpdates方法之间所有已变更的数据,一起进行更新。因此,这可能会有许多的变更数据,而 MaxErrors 就代表在更新这些数据时开发人员允许更新数据时发生错误的次数。如果ApplyUpdates在更新数据时发生了超过MaxErrors指定笔数的次数,那么这整个更新的操作便会被恢复。相反,如果发生的次数小于或等于MaxErrors,那么成功更新的数据仍然会被更新回数据源中,至于没有成功更新的数据,则可以让开发人员借助错误事件处理函数来决定如何处理这些失败的数据,我们将在异常处理的章节中详细介绍。如果传入给ApplyUpdates方法的MaxErrors参数是0,代表不允许发生任何的更新错误;如果传入的参数为-1,代表不管发生多少错误都没有关系,可以先把能够成功更新的数据更新回数据源之中。

因此,现在要把范例应用程序变更的数据更新回数据源之中便非常简单了,只需要在范例应用程序中调用TClientDataSet的ApplyUpdates方法即可。现在请在主窗体中加入一个TButton,设定它的Caption属性值为ApplyUpdate,如图1-23所示。图1-23 在范例主窗体中加入TButton控件

接着在TButton的OnClick事件处理函数中撰写如下的程序代码:

上面的程序代码调用了TClientDataSet的ApplyUpdates方法,并且传入的参数为0,这代表不允许发生任何的错误。如果在变更数据时发生了任何问题,那么DataSnap便会产生异常,让开发人员得以处理错误状况,在稍后的章节中我们会介绍如何处理DataSnap的异常状况。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载