c++ 语言程序设计 第十六章

77
C++ C++ 语语语语语语 语语语语语语 语语语语 语语语语 山山山山山山山山山山 山山山 Email: [email protected] [email protected]

Upload: yori

Post on 16-Mar-2016

126 views

Category:

Documents


10 download

DESCRIPTION

C++ 语言程序设计 第十六章. 山东师范大学管理学院 刘希玉 Email: [email protected] [email protected]. 课程目录. 第 1 章 概论 第 2 章 数据类型和表达式 第 3 章 指针和引用 第 4 章 条件、循环及编译预处理 第 5 章 函数 第 6 章 类和对象 第 7 章 继承和派生 第 8 章 多态性和虚函数 第 9 章 字符串和文件 I/O 第 10 章 MFC 应用程序概述 第 11 章 GUI 设计及菜单 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: C++ 语言程序设计 第十六章

C++C++ 语言程序设计语言程序设计第十六章第十六章 山东师范大学管理学院刘希玉Email: [email protected] [email protected]

Page 2: C++ 语言程序设计 第十六章

课程目录 第第11章 概论章 概论 第第22章 数据类型和表达式章 数据类型和表达式 第第33章 指针和引用章 指针和引用 第第44章 条件、循环及编译预处理章 条件、循环及编译预处理 第第55章 函数 章 函数 第第66章 类和对象 章 类和对象 第第77章 继承和派生 章 继承和派生 第第88章 多态性和虚函数 章 多态性和虚函数 第第99 章 字符串和文件 章 字符串和文件I/O I/O 第第1010 章 章 MFCMFC应用程序概述 应用程序概述 第第1111 章 章 GUIGUI设计及菜单设计及菜单 第第1212章 创建和使用对话框章 创建和使用对话框 第第1313章 应用程序的组成元素章 应用程序的组成元素 第第 1414 章 简单的图形和文本输出 章 简单的图形和文本输出 第第 1515 章 章 Windows Windows 标准控件 标准控件 第第 1616 章 章 Visual C++Visual C++ 数据库编程 数据库编程 第第 1717 章 章 ACISACIS 的简介与环境配置 的简介与环境配置 第第 1818 章 章 ACISACIS 的实例代码 的实例代码 第第 1919 章 程序调试章 程序调试

Page 3: C++ 语言程序设计 第十六章

第十六章 Visual C++ 数据库编程 16.1 Visual C++16.1 Visual C++ 开发数据库的特点开发数据库的特点16.2 MFC ODBC16.2 MFC ODBC 数据库访问技术数据库访问技术16.3 16.3 使用使用 DAO DAO 技术访问数据库技术访问数据库16.4 OLE DB 16.4 OLE DB 和和 ADOADO 技术概述技术概述

Page 4: C++ 语言程序设计 第十六章

16.1 Visual C++ 开发数据库的特点 Visual C++ Visual C++ 提供了多种的数据库访问技术:提供了多种的数据库访问技术: ODBC APIODBC API 、、 MFC ODBCMFC ODBC 、、 DD

AOAO 、、 OLE DBOLE DB 、、 ADOADO 等。这些技术各有自己的特点,它们提供了简单、灵等。这些技术各有自己的特点,它们提供了简单、灵活、访问速度快、可扩展性活、访问速度快、可扩展性 强的开发技术,这些正是强的开发技术,这些正是 VisuVisual C++al C++ 开发数据库程序的优势所在,归纳起来主要有以下开发数据库程序的优势所在,归纳起来主要有以下 几点:几点:

简单性简单性 Visual C++ Visual C++ 提供了提供了 MFCMFC 类库、类库、 ATLATL 模板类以及模板类以及 AppWizardAppWizard 、、 ClaClassWizardssWizard 等一系列等一系列 WizardWizard 工具,掌握它们会达到事半功倍的效果;而且工具,掌握它们会达到事半功倍的效果;而且 MFMFC ODBCC ODBC 和和 ADOADO 数据库接口已经将一些底层的操作都封装在类中,用户可数据库接口已经将一些底层的操作都封装在类中,用户可以方便的使用这些接口而无需编写操作数据库的底层代码。以方便的使用这些接口而无需编写操作数据库的底层代码。

可扩展性可扩展性 Visual C++Visual C++ 提供的提供的 OLEOLE 和和 ActiveXActiveX 技术可以让开发者利技术可以让开发者利用用 Visual C++Visual C++ 中提供的各种组件、控件以及第三方开发者提供的组件来创建中提供的各种组件、控件以及第三方开发者提供的组件来创建自己的程序,从而实现应用程序的组件化,而组建化的应用程序则会具有良自己的程序,从而实现应用程序的组件化,而组建化的应用程序则会具有良好的可扩展性。 好的可扩展性。 访问速度快访问速度快 Visual C++Visual C++ 为了解决为了解决 ODBCODBC 开发的数据库应用程序访问数开发的数据库应用程序访问数据库速度慢的问题,提供了新的访问技术——据库速度慢的问题,提供了新的访问技术—— OLE DBOLE DB 和和 ADOADO ,它们都是,它们都是基于基于 COMCOM 口的技术,使用此技术可以直接对数据库的驱动程序进行访问,口的技术,使用此技术可以直接对数据库的驱动程序进行访问,这大大提高了对数据库的访问速度。这大大提高了对数据库的访问速度。 数据源友好数据源友好 传统的传统的 ODBCODBC 技术只能访问关系型数据库,而在技术只能访问关系型数据库,而在 Visual CVisual C

++++ 中通过中通过 OLE DBOLE DB 技术不但可以访问关系型数据库,还可以访问非关系型数技术不但可以访问关系型数据库,还可以访问非关系型数据库。据库。

Page 5: C++ 语言程序设计 第十六章

Visual C++ 6.0 开发数据库的相关技术 Visual C++Visual C++ 提供了许多种访问数据库的技术,提供了许多种访问数据库的技术,如下所示:如下所示: ODBC (Open DataBase Connectity)ODBC (Open DataBase Connectity) MFC ODBC (Microsoft Foundation ClassMFC ODBC (Microsoft Foundation Class

es ODBC)es ODBC) DAO (Data Access Object)DAO (Data Access Object) OLE DB (Object Link and Embedding DaOLE DB (Object Link and Embedding Da

taBase)taBase) ADO (ActiveX Data Object)ADO (ActiveX Data Object)

Page 6: C++ 语言程序设计 第十六章

DBC 和 MFC ODBC ODBCODBC 是为客户应用程序访问关系数据库是提供的一个标是为客户应用程序访问关系数据库是提供的一个标准接口,对不同的数据库,准接口,对不同的数据库, ODBCODBC 提供了一套统一的提供了一套统一的 API,API,使得应用程序可以应用所提供的使得应用程序可以应用所提供的 APIAPI ,访问任何提供了,访问任何提供了 OO

DBCDBC 驱动程序的数据库。而且,由于驱动程序的数据库。而且,由于 ODBCODBC 已经成为一已经成为一种标准,所以现在几乎所有的关系数据库都提供了种标准,所以现在几乎所有的关系数据库都提供了 ODBCODBC的驱动程序,从而使得的驱动程序,从而使得 ODBCODBC 应用更加广泛。应用更加广泛。 由于由于 ODBCODBC 是一种底层的访问技术,因此,是一种底层的访问技术,因此, ODOD

BC APIBC API 可以使客户应用程序能够从底层设置和控制数据可以使客户应用程序能够从底层设置和控制数据库,完成一些高层数据库技术无法完成的功能。但是库,完成一些高层数据库技术无法完成的功能。但是 ODODBC PAIBC PAI 代码编制相对来说比较复杂,而代码编制相对来说比较复杂,而 MFC ODBC MFC ODBC 是是Visual C++Visual C++ 对对 ODBC API ODBC API 封装得到的,因此可以简化程封装得到的,因此可以简化程序设计,但缺点也是不言而喻的,那就是无法对数据源进序设计,但缺点也是不言而喻的,那就是无法对数据源进行底层操作。行底层操作。

Page 7: C++ 语言程序设计 第十六章

DAODAODAO 提供了一种通过程序代码创建和操作提供了一种通过程序代码创建和操作数据库的机制。多个数据库的机制。多个 DAODAO 构成一个体系结构成一个体系结构,在这个结构中各个构,在这个结构中各个 DAODAO 对象是协同工对象是协同工作的。作的。 MFC DAOMFC DAO 是微软公司提供的用于是微软公司提供的用于访问访问 Microsoft JetMicrosoft Jet 数据库文件(数据库文件( .mdb.mdb )的)的强有力的数据库开发工具,它通过强有力的数据库开发工具,它通过 DAODAO 的的封装,向程序员提供了封装,向程序员提供了 DAODAO 丰富的操作数丰富的操作数据库手段。 据库手段。

Page 8: C++ 语言程序设计 第十六章

OLE DB 和 ADO OLE DBOLE DB 是是 Visual C++Visual C++ 开发数据库应用中提供的开发数据库应用中提供的基于基于 COMCOM 接口的新技术,因此接口的新技术,因此 OLE DBOLE DB 对所有对所有的文件系统(关系与非关系数据库)都提供了统的文件系统(关系与非关系数据库)都提供了统一的接口。这些特性使得一的接口。这些特性使得 OLE DBOLE DB 技术比传统的技术比传统的数据库访问技术更加优越。它属于数据库访问技数据库访问技术更加优越。它属于数据库访问技术中的底层借口,在术中的底层借口,在 VCVC 中提供了中提供了 ATLATL 模板来设模板来设计计 OLE DBOLE DB 数据应用程序和数据提供程序。数据应用程序和数据提供程序。 而而 DAODAO 技术则是基于技术则是基于 OLE DBOLE DB 的访问借的访问借口,对口,对 OLE DBOLE DB 的接口作了封装,定义了的接口作了封装,定义了 ADOADO对象,使得程序开发得到简化,它属于数据库访对象,使得程序开发得到简化,它属于数据库访问的高层接口。问的高层接口。

Page 9: C++ 语言程序设计 第十六章

第十六章 Visual C++ 数据库编程 16.1 Visual C++16.1 Visual C++ 开发数据库的特点开发数据库的特点16.2 MFC ODBC16.2 MFC ODBC 数据库访问技术数据库访问技术16.3 16.3 使用使用 DAO DAO 技术访问数据库技术访问数据库16.4 OLE DB 16.4 OLE DB 和和 ADOADO 技术概述技术概述

Page 10: C++ 语言程序设计 第十六章

16.2 MFC ODBC 数据库访问技术 ODBCODBC 是一种使用是一种使用 SQLSQL 的程序设计接口。使用的程序设计接口。使用 ODBCODBC 让程序的编写避免了让程序的编写避免了与数据库相连的复杂性。这项技术目前已经得到了大多数与数据库相连的复杂性。这项技术目前已经得到了大多数 DBMSDBMS厂商的广泛厂商的广泛支持。支持。 Microsoft Developoer StudioMicrosoft Developoer Studio 为大多数标准的数据库格式提供了为大多数标准的数据库格式提供了 3232位位的的 ODBCODBC 驱动器,比如驱动器,比如 SQL ServerSQL Server 、、 AccessAccess 、、 ParadoxParadox 、、 ForProForPro 、、 ExcExc

elel 、、 OracleOracle 等。如果用户需要用其他的数据库格式,用户需要相应的等。如果用户需要用其他的数据库格式,用户需要相应的 ODBCODBC驱动以及驱动以及 DBMSDBMS 。。 MFCMFC 的的 ODBCODBC 类对较复杂的类对较复杂的 ODBC APIODBC API 进行了封装,提供了简化进行了封装,提供了简化的调用接口,从而大大方便了数据库应用程序的开发。程序员不必了解的调用接口,从而大大方便了数据库应用程序的开发。程序员不必了解 ODBODB

C APIC API 和和 SQLSQL 的具体细节,利用的具体细节,利用 ODBCODBC 类就可以完成对数据库的大部分操作。类就可以完成对数据库的大部分操作。MFC MFC 的的 ODBCODBC 类主要包括如下类主要包括如下 55 类:类:

CDatabaseCDatabase 类:主要功能是建立与数据源地联接。类:主要功能是建立与数据源地联接。 CRecordsetCRecordset 类:代表从数据源选择的一组记录(记录集)。类:代表从数据源选择的一组记录(记录集)。 CRecordViewCRecordView 类:提供了一个表单视图与某个记录集直接相连,利用对话框类:提供了一个表单视图与某个记录集直接相连,利用对话框数据交换机制(数据交换机制( DDXDDX )在记录集与表单视图的空间之间传输数据。)在记录集与表单视图的空间之间传输数据。 CFieldExchangeCFieldExchange 类:支持记录字段数据交换(类:支持记录字段数据交换( DFXDFX ),即记录集字段数据),即记录集字段数据成员于相应的的数据库的表的字段之间的数据交换。成员于相应的的数据库的表的字段之间的数据交换。 CDBExceptionCDBException 类:代表类:代表 ODBCODBC 类产生的异常。类产生的异常。

Page 11: C++ 语言程序设计 第十六章

使用 MFC ODBC 编程建立应用程序 相对于使用相对于使用 ODBC APIODBC API ,使用,使用 MFC ODBCMFC ODBC 访问数据库简单得多,其访问数据库简单得多,其步骤如下:步骤如下: 首先创建数据库并在系统中设置好;首先创建数据库并在系统中设置好; 使用使用 CDatabaseCDatabase 打开数据源的连接,如果利用打开数据源的连接,如果利用 AppWizardAppWizard 生成一个生成一个

ODBCODBC 数据库应用程序,则会自动完成操作。数据库应用程序,则会自动完成操作。 使用使用 ClassWizardClassWizard 想到加入由想到加入由 CRecordsetCRecordset 类派生的用户记录集,完类派生的用户记录集,完成对数据库表的绑定。成对数据库表的绑定。 创建记录积累对象,如果利用 创建记录积累对象,如果利用 AppWizardAppWizard 生成一个生成一个 ODBCODBC 数据库应数据库应用程序,则会自动在文档类中创建。用程序,则会自动在文档类中创建。 使用记录集对象对数据库进行遍历、增加、删除、和修改等操作。使用记录集对象对数据库进行遍历、增加、删除、和修改等操作。 使用使用 CDatabaseCDatabase 类的类的 ExecuteSQLExecuteSQL 函数直接执行函数直接执行 SQLSQL命令。命令。 使用使用 CDatabaseCDatabase 类的类的 BeginTransBeginTrans 、、 CommitTransCommitTrans 和和 RollbackRollback 函数函数进行事务处理。进行事务处理。 使用使用 CDatabaseCDatabase 类的类的 CloseClose 函数关闭数据源连接。函数关闭数据源连接。

Page 12: C++ 语言程序设计 第十六章

建立数据库 这里我们采用这里我们采用 AccessAccess 各式的数据库,数据各式的数据库,数据库创建过程如下:库创建过程如下: * * 创建一个名为创建一个名为 demo01demo01 的数据库;的数据库; * * 建立一个新的数据表,表名记为建立一个新的数据表,表名记为 puspus

erer ,用于存储用户信息。这里我们建立,用于存储用户信息。这里我们建立 一一个用户登录系统的界面,只要存放用户的个用户登录系统的界面,只要存放用户的 IDID ,,用户名、密码、以及权限即可。用户名、密码、以及权限即可。 将这些将这些作为表中的字段建立,并存储相应的数据。作为表中的字段建立,并存储相应的数据。如图如图 16.2.116.2.1 所示。所示。

Page 13: C++ 语言程序设计 第十六章

设置数据源 创建好数据库后我们还要进行配置,以便程序通创建好数据库后我们还要进行配置,以便程序通过过 ODBCODBC 数据源来访问刚刚创建的数据库。不同数据源来访问刚刚创建的数据库。不同的的 WindowsWindows 操作系统中数据源的配置过程不尽相操作系统中数据源的配置过程不尽相同,但差别不是很大,本例以同,但差别不是很大,本例以 Windows XPWindows XP 系统系统为例。具体操作如下:为例。具体操作如下: (( 11 )选择开始菜单“控制面板——管理工具)选择开始菜单“控制面板——管理工具——数据源(——数据源( ODBCODBC )”,弹出“)”,弹出“ ODBCODBC 数据数据源管理器”对话框,选择“系统源管理器”对话框,选择“系统 DSN”DSN”选项卡,选项卡,单击单击 [[添加添加 ]]按钮,如图按钮,如图 16.2.216.2.2 所示。所示。

Page 14: C++ 语言程序设计 第十六章

在弹出的“创建新数据源”对话框中,选在弹出的“创建新数据源”对话框中,选择“择“ Microsoft Access Driver (*.mdb)”Microsoft Access Driver (*.mdb)” ,如,如图图 16.2.316.2.3 所示,单击所示,单击 [[ 完成完成 ]] 按钮。 按钮。

Page 15: C++ 语言程序设计 第十六章

在弹出的“在弹出的“ ODBC Microsoft Access ODBC Microsoft Access 安安装”对话框中,配置数据源属性。如图装”对话框中,配置数据源属性。如图 16.16.2.42.4 所示,依次配置数据源名为“所示,依次配置数据源名为“ demo01”demo01” ,,说明为“第一个说明为“第一个 DemoDemo 的数据库”,当然的数据库”,当然此处可以省略,我们只是为了更清楚地明此处可以省略,我们只是为了更清楚地明白数据源的意义而添加此项的。单击白数据源的意义而添加此项的。单击 [[ 选选择择 ]] 按钮。 按钮。

Page 16: C++ 语言程序设计 第十六章

在弹出的“选择数据库”对话框中选择我在弹出的“选择数据库”对话框中选择我们要用作数据库的们要用作数据库的 AccessAccess 文件“文件“ demo01.demo01.mdb”mdb” ,找到“,找到“ demo01.mdb”demo01.mdb” 的路径,选的路径,选中文件,单击中文件,单击 [[ 确定确定 ]]按钮,如图按钮,如图 16.2.516.2.5 。 。

Page 17: C++ 语言程序设计 第十六章

此时退回到图此时退回到图 16.2.416.2.4 所示的“所示的“ ODBC Microsoft ODBC Microsoft Access Access 安装”对话框,可以看到其中的“数据安装”对话框,可以看到其中的“数据库”标签后面增加了一行“库”标签后面增加了一行“ E:\zdc\demo01\demE:\zdc\demo01\demo01.mdb”o01.mdb” ,这就是本例数据源所对应的数据库,,这就是本例数据源所对应的数据库,单击单击 [[确定确定 ]]按钮。按钮。

(( 66 ) 此时退回到图) 此时退回到图 16.2.216.2.2 所示的所示的““ ODBCODBC 数据源管理器”对话框,可以看到已经数据源管理器”对话框,可以看到已经存在了名为“存在了名为“ demo01 Microsoft Access Driver (*.demo01 Microsoft Access Driver (*.mdb)”mdb)” 的数据源。单击的数据源。单击 [[确定确定 ]]按钮,结束数据源按钮,结束数据源的配置过程。的配置过程。

至此数据源的配置过程完成,后面需至此数据源的配置过程完成,后面需要进行要进行 Visual C++Visual C++ 的程序编写了。的程序编写了。

Page 18: C++ 语言程序设计 第十六章

制作用户登录模块 (( 11 )打开“)打开“ Microsoft Visual C++ 6.0”Microsoft Visual C++ 6.0” ,选择,选择““ File——New”File——New” 命令菜单,弹出“命令菜单,弹出“ New”New”窗口,窗口,选择“选择“ Projects”Projects”选项卡后在列表中选择“选项卡后在列表中选择“ MFC MFC

AppWizard (exe)”AppWizard (exe)” ,确定工程名称为“,确定工程名称为“ Demo01”Demo01” ,,并选择工程存放路径。并选择工程存放路径。 (( 22 )在如图)在如图 16.2.616.2.6 所示的“所示的“ MFC MFC 应用程序向应用程序向导步骤导步骤 1”1” 对话框中,选中“基本对话框”项,我对话框中,选中“基本对话框”项,我们要创建的是一个用户登录界面,建立一个登录们要创建的是一个用户登录界面,建立一个登录对话框即可。其他保持默认值,单击对话框即可。其他保持默认值,单击 [[ 下一步下一步 ]]按按钮。钮。

Page 19: C++ 语言程序设计 第十六章

(( 33 ) 在“) 在“ MFC MFC 应用程序向导步骤应用程序向导步骤2”2” 对话框中,保持对话框中,保持各选项的默认值,单各选项的默认值,单击击 [Next][Next] 按钮。按钮。

(( 44 )在如图)在如图 16.2.16.2.77 所示的“所示的“ MFC MFC 应应用程序向导步骤用程序向导步骤 3”3”对话框中,选择第三对话框中,选择第三项“您希望使用项“您希望使用 MFMFCC 库吗?”为“作为库吗?”为“作为静态的静态的 DLL”DLL” 。其他。其他各项保持默认值,然各项保持默认值,然后单击后单击 [[ 下一步下一步 ]] 按按钮。钮。

Page 20: C++ 语言程序设计 第十六章

在如图 16.2.8 所示的“ MFC 应用程序向导步骤 4”对话框中,保持各项默认值,然后单击 [ 完成 ] 按钮。

Page 21: C++ 语言程序设计 第十六章

(( 66 )在最后弹出的对话框中,单击)在最后弹出的对话框中,单击 [[ 确确定定 ]] 按钮,完成工程的创建。按钮,完成工程的创建。 至此,基于对话框的工程创建出至此,基于对话框的工程创建出来了,整个工程包含一个程序“来了,整个工程包含一个程序“ Demo01”Demo01” ,,整个程序包含一个默认的对话框。整个程序包含一个默认的对话框。 编辑对话框资源编辑对话框资源 将主编辑区切换到要编辑的对话框上,如将主编辑区切换到要编辑的对话框上,如图图 16.2.916.2.9 所示,所示,

Page 22: C++ 语言程序设计 第十六章

添加变量 要想让对话框类中的变量接受对话框上控件的输入或向对要想让对话框类中的变量接受对话框上控件的输入或向对话框输出,必须将控件与相应的变量关联起来,以简化话框输出,必须将控件与相应的变量关联起来,以简化“控件—变量”之间频繁的数据交换,在我们要实现的用“控件—变量”之间频繁的数据交换,在我们要实现的用户登录界面中要为用户名和密码的输入作控件变量关联。户登录界面中要为用户名和密码的输入作控件变量关联。 为输入用户名的编辑框控件进行变量关联。选择“查看—为输入用户名的编辑框控件进行变量关联。选择“查看—建立类向导”菜单命令,在弹出的“建立类向导”菜单命令,在弹出的“ MFC ClassWizard”MFC ClassWizard”对话框中,切换到“对话框中,切换到“ Member Variables”Member Variables” 选项卡,如图选项卡,如图 16.16.

2.102.10 所示,然后在所示,然后在 Class nameClass name 下拉框中选择“下拉框中选择“ CDemo0CDemo01Dlg”1Dlg”项,并且在项,并且在 Control IDControl ID 单选框中选择“单选框中选择“ ID_USER_ID_USER_NAME”NAME” ,最后单击,最后单击 [Add Variables][Add Variables] 按钮。 按钮。

Page 23: C++ 语言程序设计 第十六章

进行变量定义。如图 16.2.11 ,在弹出的“ Add Member Variable” 对话框中,依次在 Member variable name 框中输入“ m_username” ,在 Category 下拉框中选择“ Value” 项,在“ Variable type” 下拉框中选择“ CString” 项,最后单击 [OK] 按钮完成设置。

Page 24: C++ 语言程序设计 第十六章

重复以上步骤,为输入密码的编辑框控件重复以上步骤,为输入密码的编辑框控件设置一个变量设置一个变量 m_userpwdm_userpwd 。。 在这个例子中只要为以上两个控件连接变在这个例子中只要为以上两个控件连接变量就足够了,完成所有的变量配置后在量就足够了,完成所有的变量配置后在““ MFC ClassWizard”MFC ClassWizard” 对话框中单击对话框中单击 [OK][OK]按钮保存刚才的设置,这样才可以起作用。按钮保存刚才的设置,这样才可以起作用。

Page 25: C++ 语言程序设计 第十六章

连接数据库我们需要创建一个我们需要创建一个 CRecordSetCRecordSet 类的派生类类的派生类

CUserRecordsetCUserRecordset 类来操作数据库“类来操作数据库“ DemoDemo01.mdb”01.mdb” 的表“的表“ puser”puser” 。。

创建创建 CUserRecordsetCUserRecordset 类。将类。将 WorkSpaceWorkSpace切换到“切换到“ ClassView”ClassView” 选项卡,如图选项卡,如图 16.2.116.2.122 ,在“,在“ Domo01Classes”Domo01Classes” 位置单击鼠标右位置单击鼠标右键,然后选中“键,然后选中“ New Class”New Class” 菜单命令。 菜单命令。

Page 26: C++ 语言程序设计 第十六章
Page 27: C++ 语言程序设计 第十六章

从 CRecordSet 派生新类“ CUserRecordset” 。在弹出的如图 16.2.13所示的对话框中,依次在 Base class 下拉框中选择“ CRecoedSet” 项,在 Name 下拉框中选择“ CUserRecordset” ,然后单击 [ 确定 ] 按钮。

Page 28: C++ 语言程序设计 第十六章

选择数据源。在弹出的 Database Option 对话框中,在 Datasource 单选框中选择 ODBC 数据源类型,然后在 ODBC数据源的下拉框中选中“ demo01” ,其他选项可以保持默认值,如图 16.2.14 ,最后单击 [OK] 按钮

Page 29: C++ 语言程序设计 第十六章

在弹出的对话框“ Select Database Tables” 中选择数据表,如图 16.2.15 ,选中我们前面创建的表“ puser” ,单击 [OK] 按钮,这时我们可以看到在图 16.2.12 所示的位置自动增加了一个“ CUserRecordset”

Page 30: C++ 语言程序设计 第十六章

到现在为止我们已经创建完了连到数据库的类到现在为止我们已经创建完了连到数据库的类““ CUserRecordset”CUserRecordset” 。这时在工作区的“。这时在工作区的“ ClassVClassView”iew” 窗口中我们可以看到在新添加的派生类“窗口中我们可以看到在新添加的派生类“ CCUserRecordset”UserRecordset” 中已经自动定义了中已经自动定义了 44 个变量,如个变量,如图图 16.2.1616.2.16 ,这,这 44 个变量正好与我们创建的表“个变量正好与我们创建的表“ ppuser”user” 中的字段同名,并且类型也是一致的。这是中的字段同名,并且类型也是一致的。这是MFCMFC 自动添加的变量,以绑定我们刚才选中的表自动添加的变量,以绑定我们刚才选中的表中的字段。需要说明的是,如果表中字段的名是中的字段。需要说明的是,如果表中字段的名是中文,则中文,则 MFCMFC 会自动创建会自动创建 m_column1m_column1 、、 m_colm_column2umn2 等这样的变量名来对应表中的字段。等这样的变量名来对应表中的字段。

Page 31: C++ 语言程序设计 第十六章
Page 32: C++ 语言程序设计 第十六章

增加“确定”按钮的消息响应代码 在我们创建的用户登录界面中,要求点击“确定”按钮时,程序能进在我们创建的用户登录界面中,要求点击“确定”按钮时,程序能进行密码验证的操作,这就要求为行密码验证的操作,这就要求为 [[确定确定 ]]按钮增加一个响应“鼠标点按钮增加一个响应“鼠标点击”的函数,实质就是重载击”的函数,实质就是重载 [[确定确定 ]]按钮的“按钮的“ OnOK”OnOK” 函数。函数。 选中“选中“ View—ClassWizard”View—ClassWizard” 菜单命令,在弹出的“菜单命令,在弹出的“ MFC ClassWizaMFC ClassWiza

rd”rd” 对话框中,选中“对话框中,选中“ Message Map”Message Map” 选项卡。选项卡。 增加消息响应函数。在弹出的如图增加消息响应函数。在弹出的如图 16.2.1716.2.17 所示的对话框中,依次在所示的对话框中,依次在

Class NameClass Name 下拉框中选择下拉框中选择 CDemo01DlgCDemo01Dlg 项,在项,在 Object IDsObject IDs 单选框单选框中选择中选择 IDOKIDOK 项,在项,在 MessageMessage 单选框中选择单选框中选择 BN_CLICKEDBN_CLICKED 项,然后项,然后单击单击 [Add Function][Add Function]按钮来为此消息增加消息响应寒暑,此时会弹出按钮来为此消息增加消息响应寒暑,此时会弹出一个确认框,保持其中的默认值并确认。操作完后我们可以看到在图一个确认框,保持其中的默认值并确认。操作完后我们可以看到在图中新增加了一行“中新增加了一行“ OnOK ON:IDOK:ON_CLICKEDOnOK ON:IDOK:ON_CLICKED”” ,这就是新增加,这就是新增加的消息响应函数。的消息响应函数。 [[取消取消 ]]按钮的响应函数与此类似,只不过它是重载了“按钮的响应函数与此类似,只不过它是重载了“ OnClose”OnClose”函数。保存刚才的设置,消息响应函数就添加完成了。此时切换到函数。保存刚才的设置,消息响应函数就添加完成了。此时切换到““ WorkSpace”WorkSpace” 的“的“ ClassView”ClassView” 选项卡,在“选项卡,在“ CDemo01Dlg”CDemo01Dlg” 类中,类中,可以看到其中增加了一个“可以看到其中增加了一个“ OnOK”OnOK” 函数。函数。

Page 33: C++ 语言程序设计 第十六章
Page 34: C++ 语言程序设计 第十六章

编写“密码验证”代码 以上我们只是为以上我们只是为 [[确定确定 ]]按钮添加了一个响按钮添加了一个响应鼠标单击消息的函数,如果我们要求在应鼠标单击消息的函数,如果我们要求在单击此按钮时能够对输入的数据进行密码单击此按钮时能够对输入的数据进行密码验证,则必须在此响应函数中增加用于密验证,则必须在此响应函数中增加用于密码验证的代码,在编辑区打开“码验证的代码,在编辑区打开“ OnOK”OnOK” 的的函数定义,在此函数中编辑添加代码如下:函数定义,在此函数中编辑添加代码如下:

Page 35: C++ 语言程序设计 第十六章

void CDemo01Dlg::OnOK() void CDemo01Dlg::OnOK() {{ // TODO: Add extra validation // TODO: Add extra validation

herehere UpdateData(TRUE);UpdateData(TRUE); CUserRecordsetCUserRecordset    m_user;m_user; TryTry {{ if(m_user.IsOpen());if(m_user.IsOpen()); m_user.Close();m_user.Close(); m_user.m_strFilter.Format("usernamem_user.m_strFilter.Format("username

='%s' and userpwd='%s'",m_Uname,m_U='%s' and userpwd='%s'",m_Uname,m_Upwd);pwd);

m_user.Open(CRecordset::snapshot,NUm_user.Open(CRecordset::snapshot,NULL,CRecordset::none);LL,CRecordset::none);

if(m_user.IsEOF())if(m_user.IsEOF()) {m_user.Close();{m_user.Close(); AfxMessageBox("AfxMessageBox(" 密码错误,密码错误,请重试!请重试! ");"); return;return; }}

else else {m_user.Close();{m_user.Close(); AfxMessageBox("AfxMessageBox(" 登录成登录成功!!功!! ");"); }} }} catch(CDBException* e)catch(CDBException* e) {{ e->ReportError();e->ReportError(); return;return; }} CDialog::OnOK();CDialog::OnOK(); }}

Page 36: C++ 语言程序设计 第十六章

下面解释一下其中用到的部分函数和方法: UpdateData(TRUE)UpdateData(TRUE) :将表单中控件的输入内容更新到所关联的变量上,也:将表单中控件的输入内容更新到所关联的变量上,也就是让位两个编辑框控件的变量就是让位两个编辑框控件的变量 m_usernamem_username 和和 m_userpwdm_userpwd获得输入值。获得输入值。 CUserRecordsetCUserRecordset    m_user:m_user: 生成一个生成一个 CUserRecordsetCUserRecordset 类的实例类的实例 m_userm_user ,,用以操作数据库中定义的表“用以操作数据库中定义的表“ puser”puser” 。。 Try{…}Catch{…}Try{…}Catch{…} ::用以捕获意外,用用以捕获意外,用 CDBExceptionCDBException 类的实例来捕获数据类的实例来捕获数据库中可能出现的错误,库中可能出现的错误, e->ReportError();e->ReportError(); 表明将错误报告到界面上。表明将错误报告到界面上。 if(m_user.IsOpen()); m_user.Close();if(m_user.IsOpen()); m_user.Close(); 判断判断 puserpuser 记录集是否打开,如果记录集是否打开,如果打开的话则关闭,以保证后边的操作能正确执行。打开的话则关闭,以保证后边的操作能正确执行。 m_user.m_strFilter.Format("username='%s'anduserpwd='%s'",m_Unam_user.m_strFilter.Format("username='%s'anduserpwd='%s'",m_Una

me,m_Upwd)me,m_Upwd) ::定义查询语言,其对应规则为:“定义查询语言,其对应规则为:“ username= m_Uname ausername= m_Uname and userpwd= m_Upwd”nd userpwd= m_Upwd” 。。

m_user.Open(CRecordset::snapshot,NULL,CRecordset::none)m_user.Open(CRecordset::snapshot,NULL,CRecordset::none) ::执行执行查询操作。查询操作。 if(m_user.IsEOF()) {…} else {…}if(m_user.IsEOF()) {…} else {…} ::判断是否已经查询到表的末尾,如果是判断是否已经查询到表的末尾,如果是的话表明没有符合的用户,用户名或密码错误,否则提示登录成功。的话表明没有符合的用户,用户名或密码错误,否则提示登录成功。 m_user.Close()m_user.Close() ::操作完后要及时关闭数据库,保证其他操作的正确执行。操作完后要及时关闭数据库,保证其他操作的正确执行。 AfxMessageBox("AfxMessageBox(" 密码错误,请重试!密码错误,请重试! ")") ::利用标准信息框,输出警告信利用标准信息框,输出警告信息。息。

Page 37: C++ 语言程序设计 第十六章

编译 选择菜单“选择菜单“ Build—Rebuild All”Build—Rebuild All” 即可编译程序。我们看到在调试区出现了大堆错误,因即可编译程序。我们看到在调试区出现了大堆错误,因为其中忘了两点重要的内容:为其中忘了两点重要的内容: 选择选择WorkSpaceWorkSpace 的的 FileViewFileView 选项卡,在编辑区打开文件“选项卡,在编辑区打开文件“ Demo01 files\Header FilesDemo01 files\Header Files

\StaAfx.h”\StaAfx.h” ,在其中加入下面的内容:,在其中加入下面的内容: #include<afxdb.h>#include<afxdb.h> 这是与这是与 CRecordSetCRecordSet调用相关的头文件声明。调用相关的头文件声明。 打开文件“打开文件“ Demo01 files\Source Files\Demo01Dlg.cppDemo01 files\Source Files\Demo01Dlg.cpp”” ,在其中加入下面的内容:,在其中加入下面的内容: #include "UserRecordset.h"#include "UserRecordset.h" 这是与这是与 CUserRecordsetCUserRecordset 调用相关的头文件声明。调用相关的头文件声明。 因为在程序中调用了因为在程序中调用了 CRecordSetCRecordSet 类,又在类,又在 CDemo01DlgCDemo01Dlg 中调用了中调用了 CUserRCUserR

ecordsetecordset 类,因此必须要作相应的头文件声明。类,因此必须要作相应的头文件声明。 重新编译,可以看到显示没有错误,编译成功。重新编译,可以看到显示没有错误,编译成功。 单击图中的红色感叹号来运行程序。单击图中的红色感叹号来运行程序。

Page 38: C++ 语言程序设计 第十六章

此时可以看到我们编辑的用户登录界面,输入用户名和密码,登录

Page 39: C++ 语言程序设计 第十六章

第十六章 Visual C++ 数据库编程 16.1 Visual C++16.1 Visual C++ 开发数据库的特点开发数据库的特点16.2 MFC ODBC16.2 MFC ODBC 数据库访问技术数据库访问技术16.3 16.3 使用使用 DAO DAO 技术访问数据库技术访问数据库16.4 OLE DB 16.4 OLE DB 和和 ADOADO 技术概述技术概述

Page 40: C++ 语言程序设计 第十六章

16.3 使用 DAO 技术访问数据库 DAODAO (( Database Access ObjectDatabase Access Object ,数据访问对象)使用,数据访问对象)使用 Microsoft JMicrosoft J

etet 数据库引擎来访问数据库。数据库引擎来访问数据库。 Visual C++6.0Visual C++6.0 提供了对提供了对 DAODAO 的封装,的封装,MFC DAOMFC DAO 类封装了类封装了 DAODAO 的大部分功能,从而的大部分功能,从而 Visual C++6.0Visual C++6.0 程序就程序就可以使用可以使用 MFC DAOMFC DAO 类方便的访问类方便的访问 Microsoft JetMicrosoft Jet 数据库。数据库。

Microsoft Jet Microsoft Jet 是一种数据管理组件,许多数据工具(如是一种数据管理组件,许多数据工具(如 AccessAccess )都)都是通过它实现其功能的,同时,通过是通过它实现其功能的,同时,通过 JetJet 引擎可以访问数据库中的数引擎可以访问数据库中的数据和数据库结构定义。据和数据库结构定义。 DAODAO 通过通过 Microsoft JetMicrosoft Jet 数据引擎提供了一套数据引擎提供了一套对象,包括:数据库对象(对象,包括:数据库对象( DatabaseDatabase )、表定义)、表定义 (TableDef)(TableDef) 、查询、查询定义对象定义对象 (QueryDef)(QueryDef) 和记录集对象和记录集对象 (Recordset)(Recordset) 等。等。 MFC DAOMFC DAO 封装封装了了 DAODAO 的功能,说到底是通过的功能,说到底是通过 Microsoft JetMicrosoft Jet 数据引擎来访问系统和数据引擎来访问系统和用户数据库中的数据的。用户数据库中的数据的。 一般来说,基于一般来说,基于 DAODAO 的的 MFCMFC 类比基于类比基于 ODBCODBC 的的 MFCMFC 类处理功能类处理功能更强。因为基于更强。因为基于 DAODAO 的类可以通过的类可以通过 ODBCODBC 驱动,也可以通过自己的驱动,也可以通过自己的数据库引擎(数据库引擎( JetJet )存取数据。)存取数据。

Page 41: C++ 语言程序设计 第十六章

DAO 支持以下 4 个数据库选项 打开访问数据库(打开访问数据库( mdbmdb 文件)。文件)。 MdbMdb 文件是一个自饱含的数据库,文件是一个自饱含的数据库,它包括查询定义、安全信息、索引、关系,当然还有实际的数据表。它包括查询定义、安全信息、索引、关系,当然还有实际的数据表。用户只需指定用户只需指定 mdbmdb 文件的路径。文件的路径。 直接打开直接打开 ODBCODBC 数据源。这里有一个很重要的限制,不能打开以数据源。这里有一个很重要的限制,不能打开以 JetJet引擎作为驱动程序的引擎作为驱动程序的 ODBCODBC 数据源,只可以使用具有自己的数据源,只可以使用具有自己的 ODBCODBC驱动程序的驱动程序的 DLLDLL 的数据源。的数据源。 用用 JetJet 引擎打开引擎打开 ISAMISAM 型(索引顺序访问方法)数据源。 即使已经设型(索引顺序访问方法)数据源。 即使已经设置了置了 ODBCODBC 数据源,要用数据源,要用 JetJet 引擎访问这些文件类型中的一种,也必引擎访问这些文件类型中的一种,也必须以须以 ISAMISAM 型数据源方式打开文件,而非型数据源方式打开文件,而非 ODBCODBC 数据源方式。数据源方式。 给给 AccessAccess 数据库附加外部表。这实际上是用数据库附加外部表。这实际上是用 DAODAO 访问访问 ODBCODBC 数据数据源的首选方法。首先要用源的首选方法。首先要用 AccessAccess 把把 ODBCODBC 表添加到一个表添加到一个 mdbmdb 文件文件上,然后依照第一选项中介绍的方法用上,然后依照第一选项中介绍的方法用 DAODAO 打开这个打开这个 mdbmdb 文件就可文件就可以了。也可以用以了。也可以用 AccessAccess 把把 ISAMISAM 文件附加到一个文件附加到一个 mdbmdb 文件上。文件上。

Page 42: C++ 语言程序设计 第十六章

需要指出的是,由于需要指出的是,由于 Visual C++6.0Visual C++6.0 不支持不支持 AcceAccess97ss97 以后版本生成的以后版本生成的 mdbmdb 数据库,所以需要将数据库,所以需要将 AAccess2000ccess2000 等生成的数据库更改格式,才可以被等生成的数据库更改格式,才可以被Visual C++6.0Visual C++6.0 所用。下面介绍如何改变所用。下面介绍如何改变 AccessAccess数据库到老版本:数据库到老版本:

首先用首先用 Access2000Access2000打开需要转换的数据库。打开需要转换的数据库。 单击菜单上面的单击菜单上面的 [[ 工具工具 ]—>[]—>[ 数据库实用工具数据库实用工具 ]—>]—>

[[转换数据库转换数据库 ]—>[]—>[ 到早期到早期 AccessAccess 数据库版本数据库版本 ]] ,,如图如图 16.3.116.3.1 所示所示

Page 43: C++ 语言程序设计 第十六章

与 ODBC 的比较 DAODAO与与 ODBCODBC 类有许多相似之处,主要有以下类有许多相似之处,主要有以下几点:几点:两者都支持对各种两者都支持对各种 ODBCODBC 数据源的访问。虽然两数据源的访问。虽然两者使用的数据引擎不同,但都可以满足用户编写者使用的数据引擎不同,但都可以满足用户编写独立与独立与 DBMSDBMS 应用程序的要求。应用程序的要求。 DAODAO 提供了与提供了与 ODBCODBC 功能相似的功能相似的 MFCMFC 类。例如类。例如

DAODAO 的 的 CdatabaseCdatabase 类对应 类对应 ODBCODBC 的 的 CdatabasCdatabasee 类, 类, CdaoRecordsetCdaoRecordset 类对应 类对应 ODBCODBC 的 的 CracorCracordsetdset 类等等。这些对应的类功能相似,他们大部类等等。这些对应的类功能相似,他们大部分的成员函数都是相同的。分的成员函数都是相同的。

AppWizard AppWizard 和和 ClassWizardClassWizard 对使用对使用 DAODAO 和和 ODBODBCC 对象的应用程序提供了类似的支持。对象的应用程序提供了类似的支持。

Page 44: C++ 语言程序设计 第十六章

一般来说,基于一般来说,基于 DAODAO 的的 MFCMFC 类比基于类比基于 ODBCODBC 的的 MFCMFC 类处理功能类处理功能更强。因为基于更强。因为基于 DAODAO 的类可以通过的类可以通过 ODBCODBC 驱动,也可以通过自己的驱动,也可以通过自己的数据库引擎(数据库引擎( JetJet )存取数据。但是,)存取数据。但是, ODBC ODBC 和和 DAODAO 访问数据库的访问数据库的机制是完全不同的。机制是完全不同的。 ODBCODBC 的工作依赖于数据库制造商提供的驱动程序,使用的工作依赖于数据库制造商提供的驱动程序,使用 ODBC APIODBC API时,时, Windows Windows 的的 ODBCODBC 管理程序把对数据库访问的请求传递给正确管理程序把对数据库访问的请求传递给正确的驱动程序,驱动程序再使用的驱动程序,驱动程序再使用 SQLSQL 语句指示语句指示 DBMSDBMS 完成数据库访问完成数据库访问工作。工作。 类类 CdaoDatabaseCdaoDatabase 提供了一个和提供了一个和 MFC ODBC MFC ODBC 类类 CdatabseCdatabse 类似的接类似的接口,但它们之间有区别,表现在口,但它们之间有区别,表现在 CdatabaseCdatabase 是通过是通过 ODBCODBC 和和 ODBCODBC驱动程序存取数据的,而驱动程序存取数据的,而 CDaoDatabaseCDaoDatabase 则是通过数据存取对象存则是通过数据存取对象存取数据的。取数据的。 DAODAO 则不需要中间环节,它直接利用则不需要中间环节,它直接利用 Microsoft Jet Microsoft Jet 数据库引擎提供数据库引擎提供的数据库访问对象集进行工作。因此缺少了中间环节,直接访问数据的数据库访问对象集进行工作。因此缺少了中间环节,直接访问数据库,所以速度比库,所以速度比 ODBCODBC 快。快。

Page 45: C++ 语言程序设计 第十六章

使用 DAO 技术访问数据库 本例是实现一个特殊的浏览器,数据库中本例是实现一个特殊的浏览器,数据库中存有被禁止的网址,访问时,如果是被禁存有被禁止的网址,访问时,如果是被禁止的网址则禁止访问,如果不是则可以浏止的网址则禁止访问,如果不是则可以浏览该网址并且可以记录访问网址的情况;览该网址并且可以记录访问网址的情况;并且可以往数据库中添加删除禁止访问的并且可以往数据库中添加删除禁止访问的网址。本节介绍的例子不是单个的模块,网址。本节介绍的例子不是单个的模块,而是一个比较简单但完整的系统,而且它而是一个比较简单但完整的系统,而且它涉及到了多个表的操作,包括对数据库的涉及到了多个表的操作,包括对数据库的读取和写入。读取和写入。

Page 46: C++ 语言程序设计 第十六章

设计数据库 创建一个创建一个 AccessAccess 数据库,命名为数据库,命名为 Demo02Demo02 ,创建两个表,,创建两个表, pDomainpDomain和和 pLogpLog 分别用来存储被禁止的网址和访问网址的记录。分别用来存储被禁止的网址和访问网址的记录。 如图如图 16.3.2 16.3.316.3.2 16.3.3 所示:所示:

Page 47: C++ 语言程序设计 第十六章

制作浏览器 创建创建 VCVC 工程工程

首先要创建一个基于首先要创建一个基于 HtmlViewHtmlView 的工程,其步骤的工程,其步骤如下:如下: 选择创建一个新的“选择创建一个新的“ MFC AppWizard(exe)”MFC AppWizard(exe)” 工程,此处我工程,此处我们命名为们命名为 Demo02Demo02 。。 在“在“ MFC MFC 应用程序向导步骤应用程序向导步骤 1”1” 对话框中,设置程序类型对话框中,设置程序类型为第一项“单文档”。为第一项“单文档”。 在“在“ MFC MFC 应用程序向导步骤应用程序向导步骤 2”2” 到“到“ MFC MFC 应用程序向导步应用程序向导步骤骤 4”4” 对话框中选择默认值。对话框中选择默认值。 在“在“ MFC MFC 应用程序向导步骤应用程序向导步骤 5”5” 中,将第三问“您希望使中,将第三问“您希望使用用 MFCMFC 库吗库吗 ?”?” 选中“作为静态的选中“作为静态的 DLL”DLL” 如图如图 16.3.416.3.4 所示:所示:

Page 48: C++ 语言程序设计 第十六章
Page 49: C++ 语言程序设计 第十六章

在“ MFC 应用程序向导步骤 6” 对话框中,选择“基类”为“ HtmlView” 类,如图,单击 [ 完成 ] 按钮,完成工程创建。

Page 50: C++ 语言程序设计 第十六章

实现“网页浏览”功能 去除工具条和状态栏等。切换到“去除工具条和状态栏等。切换到“ WorkWork

Space | ClassView | Demo02 Classes | Space | ClassView | Demo02 Classes | CmainFrame | OnCreat(LPCREATSTRCmainFrame | OnCreat(LPCREATSTRUCT lpCreateStruct)UCT lpCreateStruct)”” ,找到下面几行注,找到下面几行注释掉,如图释掉,如图 16.3.616.3.6 所示:所示:

Page 51: C++ 语言程序设计 第十六章
Page 52: C++ 语言程序设计 第十六章

去除菜单中的各项,仅保留“帮助”菜单即可。去除菜单中的各项,仅保留“帮助”菜单即可。 把窗口的标题改为“网址浏览器”,切换到“把窗口的标题改为“网址浏览器”,切换到“ WorkSpaWorkSpa

ce | ClassView | Demo02 Classes | Cdemo03App | ::Ice | ClassView | Demo02 Classes | Cdemo03App | ::InitInstance()nitInstance()”” 编辑区,修改如下代码:编辑区,修改如下代码:

Page 53: C++ 语言程序设计 第十六章

实现浏览器的功能。因为我们在建立工程的时候选择的视图基类为实现浏览器的功能。因为我们在建立工程的时候选择的视图基类为 HtHtmlViewmlView ,所以,所以 ViewView本身已经具有显示网页的能力了,只是我么还需本身已经具有显示网页的能力了,只是我么还需要提供一个输入网址的对话框,并且在输入网址之后,能够在要提供一个输入网址的对话框,并且在输入网址之后,能够在 ChtmlViChtmlViewew 中显示相应的页面。中显示相应的页面。

制作一个对话框用来输入网址。切换到“制作一个对话框用来输入网址。切换到“ WorkSpace | ResourceView | DialoWorkSpace | ResourceView | Dialogg”” 点右键选择“插入点右键选择“插入 Dialog”Dialog” ,更改对话框的名称和,更改对话框的名称和 IDID ,并且将系统自动生成的,并且将系统自动生成的两个按钮改为“确定、取消”。两个按钮改为“确定、取消”。

为该对话框加入一个新为该对话框加入一个新 EditEdit 控件用来输入网址控件用来输入网址 ,为该对话框建立新类,为该对话框建立新类 CurlDlgCurlDlg ,,并作变量映射,为并作变量映射,为 EditEdit 控件添加一个变量控件添加一个变量 m_strUrlm_strUrl ,类型为,类型为 CstringCstring 。。 在菜单中加入“浏览网址”的菜单项。注意设置在菜单中加入“浏览网址”的菜单项。注意设置 IDID 为“为“ ID_MENU_BROWSER”ID_MENU_BROWSER” 。。并且给菜单加命令函数: 并且给菜单加命令函数: CMainFrame::OnMenuBrowser()CMainFrame::OnMenuBrowser() 。。 在类在类 Cdemo02ViewCdemo02View 中增加一个函数方法:中增加一个函数方法: public void GoUrl(Cstring strUrl)public void GoUrl(Cstring strUrl) ,,并在函数体中加入如下代码:并在函数体中加入如下代码:

void Cdemo02View:: GoUrl(Cstring strUrl)void Cdemo02View:: GoUrl(Cstring strUrl) {{ Navigate2(strUrl,NULL,NULL);Navigate2(strUrl,NULL,NULL); }}

Page 54: C++ 语言程序设计 第十六章

在类在类 CmainFrameCmainFrame 中增加一个指针变量,保存中增加一个指针变量,保存 Cdemo0Cdemo02View2View 的实例,如下定义相关变量:的实例,如下定义相关变量:

public Cdemo02View *m_pHtmlView;public Cdemo02View *m_pHtmlView;

Page 55: C++ 语言程序设计 第十六章

注意在文件上方加入注意在文件上方加入 Cdemo02ViewCdemo02View 的类的类引用声明:引用声明: class Cdemo02View;class Cdemo02View; 在在 Cdemo02View::OnInitialUpdate()Cdemo02View::OnInitialUpdate() 函数体中,加入函数体中,加入 CC

mainFrame::m_pHtmlViewmainFrame::m_pHtmlView 的初始化:的初始化:

Page 56: C++ 语言程序设计 第十六章

同样要注意在文件上方加入相应的引用声明:同样要注意在文件上方加入相应的引用声明: #in#include”MainFrm.h”clude”MainFrm.h” ,另外还要在,另外还要在 CDemo02VieCDemo02Vieww 的“的“ Demo02View.hDemo02View.h”” 文件中加上声明:文件中加上声明: class class CDemo02Doc;CDemo02Doc;

在在 CmainFrame:: ::OnMenuBrowser()CmainFrame:: ::OnMenuBrowser() 函数中增加如下代码,函数中增加如下代码,完成访问网页的功能:完成访问网页的功能:

Page 57: C++ 语言程序设计 第十六章

需要注意的是还应该在相应的文件上方加上两个引用声明:

Page 58: C++ 语言程序设计 第十六章

进行网址限制 我们的目的是希望该浏览器能够对数据我们的目的是希望该浏览器能够对数据库中存有的非法网址进行限制,所单单库中存有的非法网址进行限制,所单单实现浏览功能还远远不够,我们现在加实现浏览功能还远远不够,我们现在加入网址限制的代码。入网址限制的代码。 进行网址限制要做以下几个工作:进行网址限制要做以下几个工作: 对用户输入的网址进行解析,得到其中对用户输入的网址进行解析,得到其中的域名,如“的域名,如“ 163.com”163.com” 。。 将域名同数据库中的记录匹配一下,如将域名同数据库中的记录匹配一下,如果数据库中有该域名,则是非法的,禁果数据库中有该域名,则是非法的,禁止访问。止访问。 下面我们来分别作这几项工作。下面我们来分别作这几项工作。 在在 CmainFrameCmainFrame 中增加一个函数方法:中增加一个函数方法:

public void GetValidIPAddr(char *szIpublic void GetValidIPAddr(char *szIPAddress)PAddress) ,注意其数据类型。此函数,注意其数据类型。此函数的功能是把一个字符串中的“的功能是把一个字符串中的“ http://”http://” 和和““ www.”www.”去除,此函数只是一个算法的去除,此函数只是一个算法的问题,与数据库操作无关。代码如下:问题,与数据库操作无关。代码如下:

Page 59: C++ 语言程序设计 第十六章

创建一个创建一个 CDaoRecordSetCDaoRecordSet 的派生类的派生类 CDomainDaoSetCDomainDaoSet 。切换到。切换到““ WorkSpace | ClassViewWorkSpace | ClassView ” ” ,在,在 Demo02ClassesDemo02Classes 上击右键,上击右键,选择加入“选择加入“ New Class”New Class” ,注意选择基类“,注意选择基类“ Base Class——CDaoRBase Class——CDaoRecordSet”ecordSet” ,数据源方式选择“,数据源方式选择“ DAO”DAO” ,并选择数据库为“,并选择数据库为“ Demo0Demo02.mdb”2.mdb” ,如图,如图 16.3.816.3.8 ,单击,单击 [OK][OK] ,最后再选择表为“,最后再选择表为“ pDomain”pDomain” 。。

Page 60: C++ 语言程序设计 第十六章

再 CmainFrame::OnMenuBrowser() 函数体中显示网页的代码之前,加入如下代码: void CMainFrame::OnMenuBrowser() void CMainFrame::OnMenuBrowser() {{ // TODO: Add your command handler code here// TODO: Add your command handler code here CUrlDlg m_UrlDlg;CUrlDlg m_UrlDlg; //// 弹出网址对话框弹出网址对话框 ,, 取消则退出取消则退出 if(m_UrlDlg.DoModal() != IDOK)if(m_UrlDlg.DoModal() != IDOK) return;return; //// 确定则进行网址解析确定则进行网址解析 char szURL[255];char szURL[255]; //// 将用户输入的网址复制到将用户输入的网址复制到 szURLszURL 中中 memcpy(szURL,m_UrlDlg.m_strUrl.operator LPmemcpy(szURL,m_UrlDlg.m_strUrl.operator LP

CTSTR(),sizeof(char[255]));CTSTR(),sizeof(char[255])); szURL[254] = '\0';//szURL[254] = '\0';// 末尾置零避免出事末尾置零避免出事 GetValidIPAddr(szURL);//GetValidIPAddr(szURL);// 解析网址为域名解析网址为域名

CDomainDaoSet m_DomainDaoSet;//CDomainDaoSet m_DomainDaoSet;// 判断网址判断网址是否在数据库中存在是否在数据库中存在 CString m_strSql;CString m_strSql; BOOLBOOL m_Flag = FALSE;m_Flag = FALSE;

trytry {{ if(m_DomainDaoSet.IsOpen())if(m_DomainDaoSet.IsOpen()) m_DomainDaoSet.Close();m_DomainDaoSet.Close(); m_strSql.Format("select * from pDomain where Dm_strSql.Format("select * from pDomain where D

omainName = '%s'",szURL);//omainName = '%s'",szURL);// 标准的标准的 SQLSQL 语句语句 m_DomainDaoSet.Open(AFX_DAO_USE_DEFAUm_DomainDaoSet.Open(AFX_DAO_USE_DEFAU

LT_TYPE,m_strSql,0);LT_TYPE,m_strSql,0); if(!m_DomainDaoSet.IsEOF())//if(!m_DomainDaoSet.IsEOF())// 输出匹配查询条件输出匹配查询条件记录记录 ,, 直到记录为空直到记录为空 m_Flag = TRUE;m_Flag = TRUE; if(m_DomainDaoSet.IsOpen())//if(m_DomainDaoSet.IsOpen())// 关闭记录集关闭记录集 m_DomainDaoSet.Close();m_DomainDaoSet.Close(); }} catch(CDaoException*e)catch(CDaoException*e) //// 意外捕获意外捕获

{{ e->ReportError ();e->ReportError (); //e->Delete ();//e->Delete (); return;return; }} if(m_Flag)if(m_Flag) {AfxMessageBox("{AfxMessageBox(" 您访问的网址不被允许您访问的网址不被允许 !");}!");} elseelse m_pHtmlView->GoUrl(m_UrlDlg.m_strUrl);m_pHtmlView->GoUrl(m_UrlDlg.m_strUrl); }} 同样需要注意的是,必须在本文件“同样需要注意的是,必须在本文件“ MainFrm.cppMainFrm.cpp””上加入上加入 CdomainDaCdomainDa

oSetoSet 的引用声明:的引用声明: #include”DomainDaoSet.h”#include”DomainDaoSet.h” 至此,“网址限制”的功能增加完成。至此,“网址限制”的功能增加完成。

Page 61: C++ 语言程序设计 第十六章

记录非法访问 在此系统中我们要实现对非法网址访问情况的记在此系统中我们要实现对非法网址访问情况的记录,当用户访问非法网址时,不但要发出警告,录,当用户访问非法网址时,不但要发出警告,而且还要记录下对该网址的访问情况,将访问情而且还要记录下对该网址的访问情况,将访问情况记录到表“况记录到表“ pLog”pLog” 中。因此要为“中。因此要为“ pLog”pLog” 表建表建立一个基于立一个基于 CdaoRecordSetCdaoRecordSet 的类,然后利用这个的类,然后利用这个

DaoRecordSetDaoRecordSet 向向 pLogpLog 表中写入非法访问的记录。表中写入非法访问的记录。 创建一个创建一个 CdaoRecordSetCdaoRecordSet 的派生类的派生类 CLogDaoSetCLogDaoSet ,操,操作方法与建立作方法与建立 CdomainDaoSetCdomainDaoSet 的方法相同。的方法相同。 在在 CmainFrame:: ::OnMenuBrowser()CmainFrame:: ::OnMenuBrowser() 函数体中增加函数体中增加如下代码,实现“记录访问”的功能:如下代码,实现“记录访问”的功能:

Page 62: C++ 语言程序设计 第十六章
Page 63: C++ 语言程序设计 第十六章

查看非法访问记录 我们还要实现查询非法访问记录的功能。单独用一个对话我们还要实现查询非法访问记录的功能。单独用一个对话框来显示,利用控件框来显示,利用控件 ListList 。。

增加一个菜单命令“查看访问记录”。切换到“增加一个菜单命令“查看访问记录”。切换到“ WorkSpace | RWorkSpace | Resource View | Demo02 resources | Menu | IDR_MAINFRAMesource View | Demo02 resources | Menu | IDR_MAINFRAMEE”” 的编辑状态,增加菜单“查看访问记录”,将的编辑状态,增加菜单“查看访问记录”,将 IDID 设为“设为“ ID_MID_MENU_LOG”ENU_LOG” 。。

为此菜单增加菜单命令函数:为此菜单增加菜单命令函数: CmainFrame::OnMenuLog()CmainFrame::OnMenuLog() 。各。各项保持默认值即可。项保持默认值即可。 增加一个对话框。切换到“增加一个对话框。切换到“ WorkSpace | Resource View | DemWorkSpace | Resource View | Dem

o02 resources | Dialogo02 resources | Dialog”” 的对话框资源编辑,增加一个对话框。的对话框资源编辑,增加一个对话框。并且生成新的对话框类,利用并且生成新的对话框类,利用 MFC WizardMFC Wizard ,生成一个基于,生成一个基于 CdialCdialogog 的类的类 CLOgDlgCLOgDlg 。。

在对话框中添加一个在对话框中添加一个 ListList 控件,并且设置该控件的属性,在“控件,并且设置该控件的属性,在“ StStyles”yles” 选项卡上设置“查看——报告”选项卡上设置“查看——报告” ,“,“ 排序——无”,并选中排序——无”,并选中“单个选择”,其他保持默认值。如图“单个选择”,其他保持默认值。如图 16.3.916.3.9 。。

Page 64: C++ 语言程序设计 第十六章
Page 65: C++ 语言程序设计 第十六章

为 List 控件作变量关联。方法和为 Edit 控件作变量关联相同,需要注意的就是“ Categery——Control” ,“ Variable type ——ClistCtrl” 。如图 16.3.10 所示:

Page 66: C++ 语言程序设计 第十六章

在对话框类 ClogDlg 中,增加一个 ClogDlg::OnInitDialog() 函数方法。利用类向导可以很容易完成函数的添加,选择“ Class name——CLogDlg”,“Messages——WM_INITDIALOG” 。如图 16.3.11 所示

Page 67: C++ 语言程序设计 第十六章

在 ClogDlg::OnInitDialog() 函数体中完成显示对话框的初始化函数,增加代码如下 BOOL CLogDlg::OnInitDialog() BOOL CLogDlg::OnInitDialog() {{ CDialog::OnInitDialog();//CDialog::OnInitDialog();// 初始化对话框初始化对话框 //// 设置设置 columncolumn 名称名称 m_ctrList.InsertColumn(0,"m_ctrList.InsertColumn(0," 操作类型操作类型 ",LVC",LVC

FMT_LEFT,80);FMT_LEFT,80); m_ctrList.InsertColumn(1,"m_ctrList.InsertColumn(1," 记录内容记录内容 ",LVC",LVC

FMT_LEFT,120);FMT_LEFT,120); m_ctrList.InsertColumn(2,"m_ctrList.InsertColumn(2," 访问时间访问时间 ",LVC",LVC

FMT_LEFT,150);FMT_LEFT,150);

CLogDaoSet m_LogDaoSet; //CLogDaoSet m_LogDaoSet; // 创建创建 CLogDaCLogDaoSetoSet 的实例的实例

int i = 0; //int i = 0; // 记录用户序号记录用户序号 CString m_strSQL,strTemp;CString m_strSQL,strTemp; trytry {{ if(m_LogDaoSet.IsOpen())if(m_LogDaoSet.IsOpen()) m_LogDaoSm_LogDaoS

et.Close();et.Close(); //// 设置查询条件设置查询条件 m_LogDaoSet.Open(AFX_Dm_LogDaoSet.Open(AFX_D

AO_USE_DEFAULT_TYPE,"select * from pLog order by LoAO_USE_DEFAULT_TYPE,"select * from pLog order by LogID DESC",0);gID DESC",0);

//// 输出匹配上查询条件用户记输出匹配上查询条件用户记录录 ,, 直到记录为空直到记录为空

while(!m_LogDaoSet.IsEOF())while(!m_LogDaoSet.IsEOF()) {{ //// 将将 LogTypeLogType 转换转换 switch(m_LogDaoSet.m_LogType)switch(m_LogDaoSet.m_LogType) {{ case 2:case 2: {{ m_ctrList.InsertItem(i,"m_ctrList.InsertItem(i," 访问非法网址访问非法网址 ");"); break;break; ;; }} default:default: {{ m_ctrList.InsertItem(i,"m_ctrList.InsertItem(i," 未知操作未知操作 ");"); break;break; ;; }} }} m_ctrList.SetItemText(i,1,m_LogDaoSet.m_Logm_ctrList.SetItemText(i,1,m_LogDaoSet.m_Log

Info);Info);

Page 68: C++ 语言程序设计 第十六章

//// 记录游标移到下一条记录记录游标移到下一条记录 strTemp.Format("%dstrTemp.Format("%d 年年 %2d%2d 月月 %2d%2d 日日 %2d%2d 时时 %2d%2d 分分 ",m_LogDaoS",m_LogDaoS

et.m_LogTime.GetYear(),m_LogDaoSet.m_LogTime.GetMonth(),m_LogDaoSet.m_LogTime.GetDay(),m_Loet.m_LogTime.GetYear(),m_LogDaoSet.m_LogTime.GetMonth(),m_LogDaoSet.m_LogTime.GetDay(),m_LogDaoSet.m_LogTime.GetHour(),m_LogDaoSet.m_LogTime.GetMinute());gDaoSet.m_LogTime.GetHour(),m_LogDaoSet.m_LogTime.GetMinute());

m_ctrList.SetItemText(i,2,strTemp);m_ctrList.SetItemText(i,2,strTemp); m_LogDaoSet.MoveNext();m_LogDaoSet.MoveNext(); i++;i++; }} //// 关闭记录集关闭记录集 if(m_LogDaoSet.IsOpen())if(m_LogDaoSet.IsOpen()) m_LogDaoSet.Close();m_LogDaoSet.Close(); }} //// 意外捕获意外捕获 catch(CDaoException*e)catch(CDaoException*e) {{ e->ReportError ();e->ReportError (); //e->Delete ();//e->Delete (); return FALSE;return FALSE; }} return TRUE; return TRUE; }} 在“在“ LogDlg.cpp”LogDlg.cpp” 中加入相关引用:中加入相关引用: #include”LogDaoSet.h”#include”LogDaoSet.h”

Page 69: C++ 语言程序设计 第十六章

回到菜单函数回到菜单函数 CmainFrame::OnMenuLoCmainFrame::OnMenuLog()g() 函数,在其中加入调用函数,在其中加入调用 ClogDlgClogDlg 对话对话框的代码:框的代码:

Page 70: C++ 语言程序设计 第十六章

在“在“ MainFrm.cppMainFrm.cpp”” 上方,加入上方,加入 ClogDlgClogDlg 的引用声明:的引用声明: #include”LogDlg.h”#include”LogDlg.h” 至此,“查看非法访问记录”功能也已经实至此,“查看非法访问记录”功能也已经实现,各功能模块都设计完成,运行程序,可以得到结果,。现,各功能模块都设计完成,运行程序,可以得到结果,。如图如图 16.3.1216.3.12 所示:所示:

Page 71: C++ 语言程序设计 第十六章

第十六章 Visual C++ 数据库编程 16.1 Visual C++16.1 Visual C++ 开发数据库的特点开发数据库的特点16.2 MFC ODBC16.2 MFC ODBC 数据库访问技术数据库访问技术16.3 16.3 使用使用 DAO DAO 技术访问数据库技术访问数据库16.4 OLE DB 16.4 OLE DB 和和 ADOADO 技术概述技术概述

Page 72: C++ 语言程序设计 第十六章

16.4 OLE DB 和 ADO 技术概述 OLE DBOLE DB 是是 MiscrosoftMiscrosoft 的新数据库接口,它是基于的新数据库接口,它是基于 COMCOM的。其特点在于它提供了一个调用数据库文件的统一接口,的。其特点在于它提供了一个调用数据库文件的统一接口,它既可以访问关系数据库,又可以访问非关系数据库。利它既可以访问关系数据库,又可以访问非关系数据库。利用用 OLE DBOLE DB ,客户端的开发人员在进行数据访问时只需要,客户端的开发人员在进行数据访问时只需要把精力集中在很少的一些细节上,而不用弄懂大量不同数把精力集中在很少的一些细节上,而不用弄懂大量不同数据库的访问协议。简单的说,据库的访问协议。简单的说, OLE DBOLE DB 是一种技术标准,是一种技术标准,它存在的目的是为了给用户提供一种统一的方法来访问所它存在的目的是为了给用户提供一种统一的方法来访问所有不同种类的数据源。有不同种类的数据源。 OLE DBOLE DB 的核心内容就是要求各种的核心内容就是要求各种数据存储都提供一种相同的访问接口,使得数据的使用者数据存储都提供一种相同的访问接口,使得数据的使用者(应用程序)可以使用同样的方法访问各种数据,而不用(应用程序)可以使用同样的方法访问各种数据,而不用考虑数据的具体存储地点、格式或类型。而且由于它是基考虑数据的具体存储地点、格式或类型。而且由于它是基于于 COMCOM 对象的结构,所以含有对象的结构,所以含有 COMCOM 模型的所有优点,模型的所有优点,例如接口灵活、系统稳定、健壮性好等,最重要的是例如接口灵活、系统稳定、健壮性好等,最重要的是 OLE OLE

DBDB 提供了高的数据库的访问速度。提供了高的数据库的访问速度。

Page 73: C++ 语言程序设计 第十六章

OLE DB OLE DBOLE DB 标准的具体实现是一组标准的具体实现是一组 C++ APIC++ API 函数,就像函数,就像 ODBCODBC 标准中的标准中的 ODBC ODBC

APIAPI 一样,所不同的是,一样,所不同的是, OLE DBOLE DB 的的 APIAPI 是符合是符合 COMCOM 标准的、基于对象的标准的、基于对象的使用使用 OLE DB APIOLE DB API ,可以编写能够访问符合,可以编写能够访问符合 OLE DBOLE DB 标准的任何数据源的应标准的任何数据源的应用程序,也可以编写针对某种特定数据存储的查询处理程序(用程序,也可以编写针对某种特定数据存储的查询处理程序( QueryProcessQueryProcessoror )和游标引擎()和游标引擎( CursorEngineCursorEngine ),因此),因此 OLE DBOLE DB 标准实际上是规定了数标准实际上是规定了数据使用者和提供者之间的一种应用层的协议据使用者和提供者之间的一种应用层的协议 (Application-Level Protocol)(Application-Level Protocol) 。。

OLE DBOLE DB 将传统的数据库系统划分成多个逻辑组件,这些组件之间相互独立将传统的数据库系统划分成多个逻辑组件,这些组件之间相互独立又相互通信,组建模型中的各个部分被冠以不同的名称,例如:数据提供者又相互通信,组建模型中的各个部分被冠以不同的名称,例如:数据提供者(( Data ProviderData Provider )、数据服务提供者()、数据服务提供者( Data Service ProviderData Service Provider )、业务组)、业务组件(件( Business ComponentBusiness Component )、数据消费者()、数据消费者( Data ConsumerData Consumer )。)。 由于由于 OLE DBOLE DB 和和 ODBCODBC 标准都是为了提供统一的访问数据的接口,标准都是为了提供统一的访问数据的接口,所以曾经有人疑惑:所以曾经有人疑惑: OLEDBOLEDB 标准是不是替代标准是不是替代 ODBCODBC 的新标准?答案是否定的新标准?答案是否定的。的。 ODBCODBC 标准的对象是基于标准的对象是基于 SQLSQL 的数据源,而的数据源,而 OLE DBOLE DB 对象是则是范围对象是则是范围更广泛的任何数据存储,包括邮件数据、更广泛的任何数据存储,包括邮件数据、 webweb上的文本或图形、目录服务上的文本或图形、目录服务(( Directory ServiceDirectory Service ),以及主机系统中的),以及主机系统中的 IMSIMS 和和 VSAMVSAM 数据。从这个意义数据。从这个意义上说,符合上说,符合 ODBCODBC 标准的数据源是符合标准的数据源是符合 OLE DBOLE DB 标准的数据存储的子集。符标准的数据存储的子集。符合合 ODBCODBC 标准的数据源要符合标准的数据源要符合 OLE DBOLE DB 标准,还必须提供相应的标准,还必须提供相应的 OLEDBOLEDB 服服务程序,就像务程序,就像 SQL ServerSQL Server 要符合要符合 ODBCODBC 标准,还必须提供相应的标准,还必须提供相应的 SQL ServSQL Serv

er ODBCer ODBC 驱动程序一样。驱动程序一样。

Page 74: C++ 语言程序设计 第十六章

ADO ADO(ActiveX Data Object)ADO(ActiveX Data Object) 是是 MicrosoftMicrosoft 数据库应用程序开发的新接口,是建数据库应用程序开发的新接口,是建立在立在 OLE DBOLE DB之上的高层数据库访问技术。之上的高层数据库访问技术。 ADOADO 技术基于技术基于 COMCOM ,具有,具有 COCO

MM 组件的诸多优点,可以用来构造可复用应用框架,被多种语言支持,能够组件的诸多优点,可以用来构造可复用应用框架,被多种语言支持,能够访问关系数据库、非关系数据库及所有的文件系统。另外,访问关系数据库、非关系数据库及所有的文件系统。另外, ADOADO 还支持各种还支持各种客户客户 // 服务器模块与基于服务器模块与基于 WebWeb 的应用程序,具有远程数据服务(的应用程序,具有远程数据服务( RDS(RemoRDS(Remote Data Service)te Data Service) )的特性,是远程数据存取的发展方向。)的特性,是远程数据存取的发展方向。

ADOADO 封装了封装了 OLE DBOLE DB 提供的接口,是基于提供的接口,是基于 OLE DBOLE DB 模型之上的更高模型之上的更高层应用,比起层应用,比起 OLE DBOLE DB 提供者,提供者, ADOADO 的接口可以使程序员在更高级别上同的接口可以使程序员在更高级别上同数据交互,并且保留了数据交互,并且保留了 MFC/ODBCMFC/ODBC 和和 DAODAO 的特性。的特性。 ADOADO 技术不仅可以应技术不仅可以应用于关系数据库,也可以应用于非关系数据库。可以用统一的方法对不同的用于关系数据库,也可以应用于非关系数据库。可以用统一的方法对不同的文件系统进行访问,大大简化了程序编制,增加了程序的可移植性。另外文件系统进行访问,大大简化了程序编制,增加了程序的可移植性。另外 ADADOO 的对象模型简化了对象的操作,因为它并不依赖于对象之间的相互层次作的对象模型简化了对象的操作,因为它并不依赖于对象之间的相互层次作用。大多数情况下可以只关心所要创建和使用的对象,而无需了解其父对象。用。大多数情况下可以只关心所要创建和使用的对象,而无需了解其父对象。例如,在例如,在 OLE DBOLE DB 的操作中,必须先建立数据源和数据实用程序之间的连接的操作中,必须先建立数据源和数据实用程序之间的连接才能打开一个行集对象,而在才能打开一个行集对象,而在 ADOADO 中可以直接打开一个记录对象,而无需先中可以直接打开一个记录对象,而无需先建立与数据源的连接。建立与数据源的连接。

Page 75: C++ 语言程序设计 第十六章

ADO 技术主要有以下几个特点 易使用:易使用: ADOADO 是高层数据库访问技术,所以相对于是高层数据库访问技术,所以相对于 ODBCODBC 来说具来说具有面向对象的特点。同时,在有面向对象的特点。同时,在 ADOADO 对象结构中,对象于对象之间对象结构中,对象于对象之间的层次结构不是非常明显,这也给编写数据库程序带来许多便利。的层次结构不是非常明显,这也给编写数据库程序带来许多便利。 可以访问多种数据源:和可以访问多种数据源:和 OLE DBOLE DB 一样,它可以访问关系型和非关一样,它可以访问关系型和非关系型数据库,具有很强的通用性和灵活性。系型数据库,具有很强的通用性和灵活性。 访问数据库效率高:由于它本身是基于访问数据库效率高:由于它本身是基于 OLE DBOLE DB 的,所以继承了的,所以继承了 OO

LE DBLE DB 的特点。的特点。 方便的W方便的W ebeb 应用:应用: ADOADO 可以以可以以 ActiveXActiveX 控件的形式出现,方便了控件的形式出现,方便了

WebWeb 应用程序的贬值。应用程序的贬值。 技术编程接口丰富:技术编程接口丰富: ADOADO 支持支持 VCVC 、、 VBVB 、、 VJVJ 、、 JavaScriptJavaScript 、、 VV

BScriptBScript 等脚本语言。等脚本语言。 程序占用内存少:由于程序占用内存少:由于 ADOADO 是基于组件模型对象(是基于组件模型对象( COMCOM )的访)的访问技术,所以,问技术,所以, ADOADO 生成的应用程序占用内存少。 生成的应用程序占用内存少。

Page 76: C++ 语言程序设计 第十六章

总结 16.1 Visual C++16.1 Visual C++ 开发数据库的特点开发数据库的特点 16.2 MFC ODBC16.2 MFC ODBC 数据库访问技术数据库访问技术 16.3 16.3 使用使用 DAO DAO 技术访问数据库技术访问数据库 16.4 OLE DB 16.4 OLE DB 和和 ADOADO 技术概述技术概述

Page 77: C++ 语言程序设计 第十六章

本 章 结 束本 章 结 束