第十一讲 C++ Builder中ADO控件的使用.docx
《第十一讲 C++ Builder中ADO控件的使用.docx》由会员分享,可在线阅读,更多相关《第十一讲 C++ Builder中ADO控件的使用.docx(18页珍藏版)》请在冰豆网上搜索。
第十一讲C++Builder中ADO控件的使用
河南科技大学教案首页
课程名称:
数据库开发技术
计划学时:
40
授课章节:
第十一讲C++Builder中ADO控件的使用
教学目的和要求:
让学生知道为了保证软件的质量需要一个合适的软件开发方法做指导。
了解数据库应用程序的开发过程和各阶段的任务。
教学基本内容:
课程在专业中的地位。
课程对于专业技能训练的的重要性,学习的目标,学习方法。
数据库系统、数据库应用系统体系结构、DBMS的功能、数据库应用开发环境、简单回顾关系模型、SQL语言。
教学重点和难点:
关于数据库应用系统体系结构的理解是难点。
重点是指导这门课程在专业学习中的位置,以及确定怎样的学习目标。
授课方式、方法和手段:
由于大多是以往的知识介绍和课程学习目标的要求,气氛尽可能轻松一些。
多媒体。
介绍以前的内容时不要死板地按部就班地介绍,避免重复讲课令人乏味的感觉。
作业与思考题:
•去了解一下其它几种软件体系结构
•了解当前流行的各种编程语言,选择一个自己喜欢的专攻方向,总结一下选择的理由。
•教材中列出的几种数据库应用系统,哪些数据可以保存到数据库中?
说明:
1.教案首页中各栏目内上下尺寸可自行调整
2.教案首页后续也河南科技大学教案专用纸书写,或使用A4纸打印。
第十一讲
C++Builder中ADO控件的使用
11.1BCB数据库技术概论
11.1.1ODBC、BDE与ADO
ODBC是Microsoft公司Windows开放式体系结构的数据库部件,它是若干WindowsAPI的标准命令或函数组,用户以统一的方式使用这些API来处理不同平台上的数据库信息。
ODBC已成为数据库行业的标准,每个数据库管理系统的开发商都为自己的数据库产品编制了相应的ODBC,为数据库的二次开发带来了方便。
为了对包括Office文档、邮件、Web上的文本或图形等形式的数据提供统一的访问方法,Microsoft对ODBC进行扩充,推出了新的数据访问接口标准OLEDB。
但ODBC和OLEDB使用起来都不太方便,因此Microsoft随后又对OLEDB进行了包装,推出了一种面向对象且与语言无关的数据库应用编程接口,这就是ADO(ActiveXDataObjects)。
BCB支持从ODBC到ADO的各种流行的数据库标准。
Borland数据库引擎称为BDE,它是访问各种数据库的DLL和实用程序的集合,用来访问符合ODBC标准的本地数据库和客户/服务器数据库。
针对不同的数据库,BDE提供了一组驱动器,使应用程序能够在不知道数据库的具体工作细节情况下即可进行各种数据操作。
不同版本的C++Builder所带的驱动器有所不同,但每个版本都有一个名为STANDARD的驱动器,提供本地数据库所要的一切。
而Client/Server版的C++Builder带有连接Sybase、Oracle、Informix、InterBase等数据库服务器的驱动器。
BCB对ADO的支持则是通过一组VCL的数据库组件来实现的。
经过BCB包装的ADO组件,在使用中与BDE以及其它的VCL组件有很好的兼容性,使得用BCB开发的数据库程序具有极强的适应能力。
11.1.2数据库别名
BDE可以直接访问数据库,也可以通过别名访问数据库,前者较为直接,后者则较为正规,并且具有更多的功能和更好的兼容性。
数据库别名生成后就可以在C++Builder中使用。
本地数据库使用的别名通常比较简单,它告诉BDE使用哪种驱动器和数据库文件在磁盘上的位置。
而客户/服务器数据库的别名则还包含其它信息,如打开方式、用户名和密码等。
BCB安装完成后,本地硬盘上已经设置了一个别名为“BCDEMOS”的数据库,该数据库内有许多表,我们经常在例题中使用该数据库别名。
下面介绍如何生成BDE的数据库别名。
在Windows系统的控制面板中选取“BDEAdministrator”图标,此时弹出BDE别名管理器,如图11-1所示。
该窗口左下方Database页上列出了系统所有的可用数据库的别名,打开其中的树型结点可以浏览更加详细的内容。
图11-1BDE管理器
作为例子我们创建一个基于FOXPRO的BDE别名MYBDE,具体方法如下:
(1)在别名管理器的Database页面上选择主菜单Object→New,或右击树型结构的任意地方,选择弹出菜单的New选项,弹出新别名对话框,如图11-2所示。
在下拉列表框中选择“STANDARD”,此时生成一个缺省名为“STANDARD1”的别名。
图11-2新建数据库别名
(2)将别名命名为“MYBDE”并回车,然后在该别名的设置中单击DEFAULTDRIVER的属性值,选取FOXPRO。
(3)将别名的PATH设置为数据库所在的目录,如路径为
C:
\ProgramFiles\Borland\BorlandShared\Data
(4)单击工具栏中的Apply按钮,即完成了别名的创建。
如果需要浏览数据库别名所指的数据库及其数据表,则单击别名前面的“+”,展开后再打开Tables节点,将出现该数据库所有可用的表,如图11-3所示。
图11-3展开后的数据库浏览器
11.1.3DatabaseDeskTop
DatabaseDeskTop是Borland公司的一个小型数据库管理系统产品。
C++Builder中可以使用DatabaseDeskTop来创建、浏览和修改本地的Paradox和dBASE数据表。
执行Tools→DatabaseDeskTop菜单命令即可打开DatabaseDeskTop。
在DatabaseDeskTop中可以打开子窗口对数据表进行创建、查询、执行SQL语句等操作。
DatabaseDeskTop子窗口主要有以下三种。
1.查询窗口
打开或建立新的QBE文件时,DatabaseDeskTop将打开一个查询窗口,可以使用查询窗口检索表中的信息。
2.SQL编辑器
当打开或创建SQL文件时,SQL编辑器窗口就会自动出现在主窗口上面。
SQL编辑器除了具有文本编辑器的一般特征以外,还具有执行和保存SQL语句的功能。
在执行时,由SQL服务器进行文法检查。
3.表窗口
当打开或建立新的Paradox、dBASE、SQL表时,会出现表窗口,利用表窗口可以输入或修改表的结构。
DatabaseDeskTop支持Paradox、dBASE和SQL文件格式,在DatabaseDeskTop中建立一个表的步骤如下:
(1)选择File→New→Table,或右击“OpenTable”工具按钮选择“New”,DatabaseDesktop将打开“CreateTable”对话框,从下拉式列表框中选择“Paradox”(如果建立其它类型的数据表,也只要在这里作相应选择即可)。
单击“OK”,DatabaseDeskTop将打开创建数据表对话框。
(2)在“FieldName”列输入字段名。
移动光标到“Type”列,按下“空格”键或用鼠标右击“Type”列,从显示的数据类型列表中选择该字段的数据类型。
在“Size”列键入一个合适的字段宽度(如果需要的话)。
(3)使用向下箭头,重复如上步骤,直到指定所需的所有字段。
(4)可以双击某字段的“Key”列将该字段指定为一个键。
Paradox表可以有一个或几个键,但必须是该表最前面的几个字段。
被指定为Key的字段会被自动索引,并且系统会检查键值组合的惟一性(即不允许两条记录的所有键值都相同)。
(5)表结构创建完成之后,选择“SaveAs”命令按钮为该表命名并保存。
在DatabaseDeskTop的表窗口中设计表的结构如图11-4所示。
在DatabaseDeskTop中可对数据表进行输入或编辑,具体步骤如下:
执行File→Open菜单命令打开数据表,执行Table→EditData菜单命令进入编辑模式,在该模式下可输入或编辑数据。
在编辑完一条记录并进入下一条记录的编辑后,DatabaseDeskTop将自动保存刚才输入或编辑的记录。
如果要修改表的结构,则应在打开表窗口之后执行Table→Restructure菜单命令
图11-4使用DatabaseDeskTop设计表的结构
11.1.4BCB的数据库组件
BCB数据库组件分为两大类:
非可视的数据访问组件和可视化的数据控制组件。
前者提供了取得数据的机制,它们位于组件面板的DataAccess、BDE和ADO等页上;而后者主要用于浏览和编辑数据,它们位于DataControls页上。
11.2数据库组件的连接
VCL的数据访问组件和数据控制控件之间通常使用DataSource来连接。
下面这个简单的例子让我们对BCB使用组件连接数据库的技术有感性的认识。
【例11-1】本例使用数据库组件连接位于本地的BCDEMOS数据库中的animals数据表进行浏览。
具体制作步骤如下:
(1)新建一个项目,在主窗体上放一个TTable类组件Table1(位于BDE组件页)。
将它的DatabaseName属性设置为BCDEMOS,它的TableName属性设置为animals.dbf。
(2)在窗体上放置一个TDataSource类组件Database1(位于DataAccess页),并在其属性Dataset的下拉框中选取Table1,实现数据源和数据集相联系。
(3)将一个TDBGrid类控件(位于DataControls页)放到窗体上,将其DataSource属性设置为DataSource1,使其与数据源相联系。
(4)回到Table1组件上,将其Active属性设置为true(缺省值为false),这样就打开了数据源,此时ANIMALS.DBF表中的数据立即显示在DBGrid1的栅格中(除BMP字段外)。
可调整DBGrid控件的大小以便于浏览。
(5)再将一个TDBImage类控件(位于DataControls页)放置在窗体上,将其DataSource属性设置为DataSource1,DataField属性设置为BMP(animals表中的字段名,数据类型为图片),并调整该控件的尺寸和位置。
(6)将一个TDBNavigator类控件(位于DataControls页)放置在窗体上,将其DataSource属性设置为DataSource1。
至此,程序设计完毕。
运行该程序,通过DBNavigator按钮可以实现添加和删除记录等功能,在DBImage中显示图片,如图11-5所示。
图11-5简单的数据表浏览程序
11.3TDataSet类
TTable组件用于方便快捷地访问本地数据表,而处理SQL数据库服务器则通常使用TQuery组件,它们都是TDataSet的派生类。
本节将对TDataSet类属性和方法的用法作一个较为详细的介绍,它们是BCB数据库技术的重要基础。
11.3.1连接数据库
与连接数据集有关的属性和方法主要有下面两点。
1.DatabaseName属性
DatabaseName属性用来指定当前使用的数据库。
在程序的设计阶段,可在ObjectInspector中进行设置,通常只要在如图5-6所示的组合框中选择一个已定义的数据库别名即可。
此外,DatabaseName也可以在程序运行时动态设置。
如果没有设置过数据库别名,那么也可以对DatabaseName属性输入数据表文件所在目录的路径。
例如,当数据表文件与应用程序项目在同一目录下时,只要对DatabaseName属性输入“.\”即可。
图11-6选择数据库
2.TableName属性
TableName属性用来指定数据表的名称,在设置TableName的属性值之前,应该首先设置DatabaseName属性的值。
如果DatabaseName属性的值是在设计阶段指定的,则可通过选择下拉列表框中有效表名来指定TableName。
11.3.2打开和关闭数据表
打开和关闭数据表的有关属性和方法主要有下面三点。
1.Active属性
如果Active属性为true,相当于调用Open方法打开数据集,使数据集处于Browse状态。
如果设置为false,相当于调用Close方法关闭数据集。
在程序的运行阶段,在设置DatabaseName的值之前,必须首先将Active属性的值设置为false,然后可设置DatabaseName的值,最后再打开该数据集。
2.Open方法
Open方法用于打开数据集,使它处于Browse状态,相当于把Active属性设置为true。
3.Close方法
Close方法用于关闭数据集,使它处于非活动状态,相当于把Active属性设置为false。
5.3.3浏览记录
浏览记录的有关属性和方法主要有下面七点。
1.Bof属性
Bof属性为只读。
如果当前记录是数据集中的第一条记录,Bof属性返回true,否则返回false。
当程序刚打开一个非空的数据集或调用了First过程时,Bof为true。
2.Eof属性
Eof属性为只读。
如果当前记录是数据集中的最后一条记录,Eof属性返回true,否则返回false。
当程序打开一个空的数据集或调用了Last过程时,Eof为true。
3.RecordCount属性
RecordCount只读属性返回数据集中的记录数。
值得注意的是:
RecordCount属性返回的记录数与数据物理存储的记录数可能不同,因为有可能使用了过滤。
4.First、Last、Next和Prior方法
First、Last、Next和Prior方法分别将数据集在过滤范围内的第一条记录、最后一条记录、下一条记录和上一条记录设置为当前记录。
5.IsEmpty方法
如果数据集是空的,IsEmpty函数就返回true。
6.MoveBy方法
MoveBy方法用于移动当前记录。
例如,MoveBy(-2)将位于当前位置前面的第二条记录变成当前记录,MoveBy(3)将位于当前位置后面的第三条记录变成当前记录。
7.Refresh方法
当使用数据控制控件如DBGrid显示数据时,可以调用Refresh方法刷新数据,使显示的数据总是数据集中最新的。
当处于网络环境时,该方法尤其重要。
11.3.4编辑数据
编辑数据的有关属性和方法主要有下面六点。
1.CanModify属性
CanModify属性仅可在运行期间使用,且为只读。
如果CanModify属性为false,表示不能修改(可能是由于多用户操作时数据集已被其他用户加锁等原因)。
不过即使CanModify属性返回true,也并不意味着数据集一定能修改,还要取决于其它因素。
2.Modified属性
Modified属性是运行期间只读的属性,如果返回true表示当前记录某个字段被修改了但还没有被写到数据集中,当程序调用Cancel或Post后,这个属性将变为false。
3.Edit方法
调用Edit方法使数据集处于编辑状态。
4.Insert方法
为了在表中插入一个记录,首先应将记录指针移到表内适当位置,接着用Insert方法建立一条空记录,然后填充记录的各字段,最后将记录写入数据库表中。
例如,下面的一段代码是调用Insert方法插入一条记录:
void__fastcallTForm1:
:
ButtonInsertClick(TObject*Sender)
{
Table1->First();
Table1->MoveBy(5);
Table1->Insert();
Table1->FieldByName("Name")->Value="NoBody";
Table1->FieldByName("Capital")->Value="NoWhere";
Table1->FieldByName("Continent")->Value="Imagination";
Table1->FieldByName("Area")->Value=0;
Table1->FieldByName("Population")->Value=0;
Table1->Post();
5.Append方法
Append方法的用法类似Insert,但总是将空记录插入到表的尾部。
6.Delete方法
删除记录可采用Delete方法,程序示例如下:
void__fastcallTForm1:
:
ButtonDeleteClick(TObject*Sender)
{
if(MessageDlg("确实要删除这条记录?
",mtConfirmation,
TMsgDlgButtons()<Table1->Delete();
}
11.3.5访问字段
访问字段的有关属性和方法主要有下面三点。
1.FieldCount属性
FieldCount属性在运行期间为只读,返回数据集中字段(列)的个数。
2.Fields属性
Fields属性是由数据集中所有字段构成的数组,每个数组元素都是一个TField对象。
例如,以下代码将Tabel1数据表中所有字段的名称加入到一个列表框中显示:
for(inti=0;iFieldCount;i++)
ListBox1->Items->Add(Table1->Fields[i]->FieldName);
3.FieldByName方法
FieldByName方法非常重要,主要用于通过字段名访问当前记录的某个字段,使用时应确保数据集中有这个字段,否则将触发一个异常。
当不能确定数据集中是否含有某个字段时,可调用FindField方法进行检测。
11.3.6过滤操作
过滤数据集是常用的操作之一,主要适用于本地数据库。
而客户/服务器数据库主要通过SQL查询来实现与本地数据库过滤相同的功能。
有时数据集中的记录较多,而其中有一些不是你所需要的部分,此时就可以进行过滤。
比如存储学生信息的数据库表,其中包含学生的学号、姓名、性别、年龄、籍贯等信息,如果只需要女同学的信息,就可以按照性别进行过滤,从而得到需要的信息。
Table组件可通过Filter属性进行过滤。
可以在设计时在ObjectInspector中输入Filter属性,也可以在程序运行时将字符串值赋给Table组件的Filter属性。
注意:
仅当Filtered属性设置为true时过滤有效。
基本过滤语句的格式如下:
FieldNameConstString;
其中,FieldName表示过滤的字段名,op是用于过滤条件的操作符,常见的操作符如表5-1所示,ConstString一般代表一个常量,如语句“性别='女'”表示显示所有女同学的信息。
其中的逻辑操作符用来连接多个基本过滤语句,例如:
CITY='NewYork'ANDSTATE='Ca';
在过滤语句中,字段名和逻辑操作符一般与大小写无关。
如果字段名内含有空格如CityName,则使用该字段名时,应使用“[]”,例如:
[CityName]='NowYork'andstate='Ca';
表11-1常见的过滤操作符
对于搜索文本的情况,FilterOptions属性可决定搜索时是否考虑大小写。
启用部分比较时,指定STATE='M*'之类的过滤器可以使记录集中包含STATE字段以M开头的所有记录。
值得注意的是,过滤操作符与一般C++编程中使用的逻辑操作符是有一些区别的。
如“不等于”过滤操作符为<>,而相应的C++操作符为!
=。
另外,字符串在过滤操作时一般是放在单引号中的,而C++字符串放在双引号中。
11.3.7查找记录
查找记录的方法有很多,这里所讲的方法适用于TDataSet所有的派生类,而不仅仅是Table组件。
但对于客户/服务器数据库,查找通常是通过SQL查询进行的。
Table组件主要使用FindFirst、FindNext、FindPrior和FindLast方法查找记录,这些方法适合于搜索过滤的记录集。
另一种搜索方法是使用FindKey和GotoKey以及GotoNearest和FindNearest。
这些方法只能对已设置为Key的字段进行查找。
此外,还可以使用Locate和Lookup方法搜索数据表。
其优点是不必过滤数据集也不需要使用键就能搜索。
其中Locate还能自动优化搜索,如果数据表有索引,则Locate使用该索引提高搜索速度。
使用GotoKey方法查询数据表中记录的步骤如下:
(1)确保要查找的字段是关键字或已经为它定义了辅助索引,并且已在Table组件的IndexName或IndexFieldNames属性中指定索引或关键字。
IndexName和IndexFieldNames用法稍有不同,可以在设计时或运行时设置这两个属性,但不能同时使用这两个属性。
(2)通过调用SetKey方法,把Table组件设置成查找模式。
(3)把查找值送进被查找字段的查找缓冲区。
(4)调用Table组件的GotoKey方法,如果查找成功,GotoKey返回true值,表中记录指针指向找到的记录。
如果查找失败,GotoKey返回false值,表中记录指针不发生变化。
【例11-2】在窗体上放入Table、DataSource、DBGrid组件各一个。
指定Table1的DatabaseName属性为BCDEMOS,TableName属性为Customer.db,Active属性为true;DataSource1的DataSet属性为Table1;DBGrid1的DataSource属性为DataSource1。
再往窗体上放入一个TEdit、两个TLabel和两个TButton控件。
当用户在Edit1控件输入客户编码并单击查找按钮时,程序便开始在Customer表中查找该客户号。
如果查找成功,则在Label2上显示“查找成功”,该客户的电话号码就会显示在标签Label1上,并且在数据表栅格中加亮显示该记录。
程序运行时如图11-7所示。
范例中“查找”按钮的OnClick事件代码如下:
void__fastcallTForm1:
:
Button1Click(TObject*Sender)
{
Table1->IndexFieldNames="CustNo";
Table1->SetKey();
Table1->FieldByName("CustNo")->AsString=Edit1->Text;
if(Table1->GotoKey())
{
Label2->Caption="查找成功";
Label1->Caption=Table1->FieldByName("Phone")->AsString;
}
else
{
Label2->Caption="查找失败";
}
}
图11-7使用GotoKey查找
【例11-3】先建立一个职工情况表ZG.db,其中一个字段为XM(姓名)。
在程序窗体上放入Table1、DataSource、DBGrid组件各一个并使它们与ZG表连接。
在Form1上再放上一个编辑框和一个“查找”按钮,当点击按钮时,程序在ZG表中查找XM与编辑框中内容相一致的第一条记录并在DBGrid内显示。
下面是程序中“查找”按