数据访问

访问|数据

     服务器组件一般用于实现三层应用程序的业务规则,因此需要与数据库交互。C++访问数据有两种方式: ADO和OLE DB消费者模板。第1 2章我们已经讨论了通用数据访问(UDA)、ADO和OLE DB的作用。
    从C++ ADO与从ASP或Visual Basic访问ADO非常相似。使用完全一样的ADO COM对象(如ADODB.Recordset),只是用不同的语言创建和使用ADO COM对象。但使用ADO时没有Visual C++向导,必须编写所有的实现代码。这不仅须手工编写,而且还容易引入代码错误,因此应认真仔细。但是可从C++中得到完全可用的ADO对象模型。
    OLE DB消费者使用OLE DB提供者的服务访问数据。ADO是OLE DB消费者的一个例子。使用C++可创建OLE DB消费者,完全跳过ADO层。Visual C++向导可用于创建和使用OLEDB消费者。可以使用向导指向想要访问的数据库和表格,自动生成所需的代码。但是,因为消费者代码直接指向指定的数据库,所以不如使用ADO灵活。
18.3.1 通过C++使用ADO
    通过C++使用ADO需要两种技能:理解ADO对象模型和在C++中使用COM对象。我们对ADO对象模型已非常熟悉,但现在没有C++类库或模板库支持ADO。因为ADO在COM上构造,使用ADO与使用其他COM对象相同。下面介绍一下使用步骤。
    1. 设置使用ADO
    C++中使用COM组件最简单的方法是用# import关键字导入组件的类型库。# import 指令围绕ADO类型库产生瘦C++类,可以用接近于VBScript和Visual Basic的语句操作ADO对象和接口。大部分ADO例子用VBScript编写,用#import指令能很容易地将它们转换为C++,比在没有包装类(wrapper class)的情况下使用ADO容易。
    使用#import时,可以使用no_namespace属性,这样ADO类型库内容就没有范围限制。但是,这会引起名称与EOF的冲突,而rename属性可解决这个问题。在TableStorage2.cpp增加下列内容可导入ADO类型库。

    上述代码生成一个msADO15.tlh文件和一个msADO15.tli文件。msADO15.tlh文件包含前向引用、smart指针声明和typeinfo声明。msADO15.tli文件包含编译器产生的几个成员函数的实现。这两个文件用于观察和显示类型库中的可用内容。例如,下面是msADO15.tlh文件对ADO记录集的smart指针的声明:
    _COM_SMARTPTR_TYPEDEF(_Recordset,_uuideof(_Recordset));
    后面的例子将说明如何在代码中使用smart指针。在msADO15.tlh中还有一些枚举量的声明,使得使用ADO更为方便。下面是光标位置的枚举量声明:

    如上所述,#import使得ADO的使用更为轻松,因为这个指令可自动创建包装类和来自类型库的类型信息。但对C++程序员来说,将ADO返回的VA R I A N T数据类型转变为C/C++数据类型还是比较麻烦。ADO 2.0和Visual C++ 6.0用附加的ADO VC++扩展解决了这个问题。这一章不讨论ADO VC++扩展,有关内容可参考Visual C++文献。
    还增加了一个宏,这个宏可使程序容易理解,减少了嵌套代码的数量:

    通过导入类型库,已可使用所有ADO对象。下面介绍如何在C++中使用ADO进行读写。我们将以图1 8 - 1 0所示的数据库为例。

    假设对这个数据库已建立了一个称为MusicianDSN的ODBC连接。
    2. 读数据库
    首先在ITableStorage2中增加Read方法。这个方法从数据库读记录,并将这些记录插入STL数据结构中,它的参数是DSN名称、用户名和口令。在对话框中,参数在Implementation文本框中出现,如图1 8 - 11所示。

    下面看一下这个方法的实现:

    首先声明方法中使用的变量,注意如何使用ATL smart指针的创建ADO Connection和Recordset对象。为在代码中跟踪错误,我们采用了异常处理,因此开启一个try块。任何ADO调用都用前面声明的SAFE_CALL宏包装,如果任一方法调用返回一个表明失败的值,就抛出一个异常:

    首先打开到数据库的连接,这个连接用于Recordset对象的Open方法。

    如果成功,可对数据库的记录进行遍历。首先必须确保内存中当前无数据:

    现在,将数据库中的数据拷贝到内存中的STL数据结构内,遍历记录直到遇到文件结束标志EOF。只在字段真的有值时才插入它,这样可以节约内存:

    到目前为止,所有一切都在try 块中。如果有错误出现,程序流将进入catch 块。_com_error变量包含了错误消息的细节,我们添加了一个辅助函数将错误的详细数据格式化为字符串。我们将这个错误字符串传送到Error中,这样,在客户端可以通过Error对象的Description属性得到它。

    上面讲述了如何从数据库中读数据,下面讨论如何将数据写入数据库。
    3. 写数据库
    在ITableStorage2中添加下列方法。它将S T L数据结构中的信息写入数据库中。操作界面如图1 8 - 1 2所示。



    另外一个差异是C++不能很好地支持Variant类型。上面的例子的代码看上去不错,但它仅由字符型数据组成。如果数据类型混用的话,代码将变得混乱。下面介绍的OLE DB者消费模板将使代码变得简洁。
18.3.2 OLE DB消费者模板
    OLE DB消费者模板是一个相对新的方法,其目的是改善在C++中进行数据存取的性能。它在Visual C++ 6.0 中作为ATL 3.0的一部分引入使用库扩展了C++功能,OLE DB消费者模板库是为了通过OLE DB进行数据存取而设计的。这个库能够提供:
    ? 访问OLE DB特征。
    ? 集成ATL和MFC。
    ? 数据库参数和列的绑定模型。
    ? 使用原有的C/C++数据类型进行OLE DB编程。
    另外,Visual C++的AppWizard可生成基本的OLE DB消费者代码。
    1. 创建OLE DB 消费者
    在创建OLE DB消费者前必须建立数据源,我们采用与ADO例子中所用的数据库相似的Access数据库。用在ATL Object Wizard添加一个新的ATL对象,选择Data Access类别并选择Consumer,如图1 8 - 1 3所示。

    点击Next,选择所需的OLE DB 提供者,因为我们选用了ODBC驱动程序,所以选择Microsoft OLE DB Provider for ODBC Drivers。如图1 8 - 1 4所示。

    选择所用的数据源名称为Musician DSN。用户名和口令没有输入,如果数据库需要用户名和口令,可在此对话框中输入,如图1 8 - 1 5所示。

    点击OK按纽,然后选择所需的数据库表,如图18 - 1 6所示。

     再点击OK,向导将自动选取一些名称,根据自己的需要可进行修改。如果将要添加记录,可在Support部分选择insert框,如图1 8 - 1 7所示。

     点击OK后,向导产生两个类: CMusiciansAccessor和CMusicians,可完成数据类型转换等工作。我们将只直接使用CMusicians类,下一节再做说明。
     2. 读数据库
     下面在ITableStorage2中添加使用新的OLE DB消费者类读数据库的方法,由ATL ObjectWizard生成的Read2不带任何参数,因为ATL Object Wizard已经将数据源名称、用户名和口令(如果你提供了)硬编码进CMusicians类,如图1 8 - 1 8所示。

    OLE DB消费者模板版本的Read2方法的代码比ADO版本的代码更为简单:

    如果上述代码没有编写的话,应在TableStorage2.cpp文件的顶部包含Musicians.h文件。
    大部分工作已由theMusicians对象完成。当调用Open后,就创建了与数据库的连接,而且打开了Musicians表。下面的代码建立数据结构,列名称映射由手工创建:

    下面遍历数据库记录。在使用OLE DB 消费者模板时,要判定记录的结束,应检查MoveNext的返回值而不是检查EOF属性。当调用MoveNext时,theMusicians对象的成员变量自动填充,在读下一个记录前,必须先调用ClearRecord,否则当该记录的字段为NULL时,前一记录的数据仍将占据成员变量。


    上述代码比ADO例子中的相应代码简洁得多。下面介绍写记录。
    3. 写数据库
    在ITableStorage2中再增加一个称为Write2的新方法,数据库配置信息已经在CMusicians类中硬编码,因此不必向Write2传送任何参数,如图1 8 - 1 9所示。

    代码的开始与Read2相似,大部分工作由theMusicians对象完成。首先调用Open以连接数据库和表。为了在数据库中添加一个记录,先填充成员变量,然后调用Insert。对一个新记录来说,应首先调用ClearRecord,确保没有前一记录的数据遗留下来。

    上面使用了称为C o p y Va l u e的辅助方法。查找记录中的字段的值是重复性的工作,可用此方法减少代码的数量:


18.3.3 使用ADO,还是使用OLE DB消费者模板
    进行数据存取时,可选用ADO或OLE DB消费者模板。选用ADO可重新利用你对ADO对象模型的知识,代码修改也较容易,灵活性好。但ADO不能很好地支持绑定到C++的数据类型,并且Visual C++中没有相应的库和AppWizard支持。
    选用OLE DB消费者模板可从Visual C++得到库和AppWizard支持。这意味着, VisualC++提供项目的基本结构,代码编写的速度较快,出现的错误也较少,但必须学习新的用于访问数据的API。如果你要编写许多需要访问数据的组件,那么这是值得的。
    本章创建了一个简单的C++服务器组件并增强其功能。我们介绍了如何访问ASP内置对象,如何访问各种COM+接口。描述了数据存取的两种方法。C++中可使用ADO对象模型,但需要进行大量的数据类型转换。ATL Object Wizard可创建OLE DB消费者,生成的代码比ADO简洁,但灵活性较差。

时间: 2024-10-28 11:05:36

数据访问的相关文章

了解 XML实现通用的数据访问

xml|访问|数据   了解可扩展标记语言 (XML) 如何帮助我们实现通用的数据访问.XML 是一种基于 Unicode 的纯文本元语言,即一种用于定义标记语言的语言.它不依赖于任何编程语言.操作系统或软件供应商.XML 可以提供对各种数据处理.构建.转换和查询技术的访问.(本文包含一些指向英文站点的链接.)  简介     最初设想的可扩展标记语言 (XML) 用于为 Web 定义新文档的格式.XML 由标准通用标记语言 (SGML) 衍生而来,可以认为它是一种元语言,即一种定义标记语言的语

JSP中早就有了类似.Net DataSet那样的离线数据访问

js|访问|数据 JSP中早就有了类似.Net DataSet那样的离线数据访问了,抛弃ResultSet,拥抱Result吧! 微软的.NET平台上面的数据访问有一个特点,就是数据查询的结果,可以放在内存中,以XML格式进行描述,不需要一直与数据库保持在线连接,用DataSet + Data Adapter来实现! 而在JDBC中,我们通常使用javax.sql.ResultSet类来存放放回的数据,它的流程和生命周期如下: 使用ResultSet来返回数据库查询结果 Client --> C

设计.NET应用程序数据访问层五大原则

程序|访问|设计|数据 摘要:大多数使用.NET框架组件工作的开发人员的一个核心工作是实现数据访问功能,他们建立的数据访问层(data access layer)是应用程序的精华部分.本文概述了使用Visual Studio .NET和.NET框架组件建立数据访问层需要考虑的五个想法.这些技巧包括通过使用基类(base class)利用面相对象技术和.NET框架组件基础结构,使类容易继承,在决定显示方法和外部界面前仔细地检验需求. 如果你正在建立以数据为中心(data-centric)的.NET

ADO数据访问模型初学者入门

ado|初学|访问|数据 ADO(ActiveXDataObjects)是Microsoft提供和建议使用的新型的数据访问接口,具体实现为Automation.这样,程序员可以在各种支持Automation的开发环境下方便地访问ADO对象,如VisualBasic.VisualC++.VisualJ++及Delphi等.ADO被实现为OLEDB之上的一个薄层,这使得ADO可以有更快的访问速度,更易使用,同时更节省资源.值得注意的是,对于VisualStudio6.0的用户而言,现在提供的ADO2

ASP.NET2.0中使用数据源控件之异步数据访问

asp.net|访问|控件|数据|数据源|异步 摘要:本文是介绍数据源控件的系列文章中的第三篇.在本文中,Nikhil 着重介绍如何执行并封装异步数据访问,同时演示可重用的异步数据访问框架,该框架根据 Microsoft Visual Studio 2005 中的可用功能来建立. 在第 1 部分和第 2 部分中,建立了 WeatherDataSource 控件,该控件针对 weather.com(英文)所提供的 XML API 来运行,使用 WebRequest 和 WebResponse 来通

.NET 数据访问体系结构指南一

访问|数据|体系  ADO.NET 引入的主要变化之一是用 DataTable.DataSet.DataAdapter 和 DataReader 对象的组合取代了 ADO Recordset 对象.DataTable 表示单个表中行的集合,在这一方面类似于 Recordset.DataSet 表示 DataTable 对象的集合,同时包括将各种表绑定在一起的关系和约束.实际上,DataSet 是带有内置 XML 支持的.内存中的关系结构. DataSet 的主要特性之一是它不了解可能用来填充它的

基于HTTP 的数据访问

   除了XML 技术之外,Microsoft SQL Server 2000 的开发者们也把通过HTTP 访问的特性(HTTP access9 作为SQL Server 2000 的一个核心特性.这样用户完全可以把SQL Server 放到一个URL 上了,从而保证开发人员和潜在的最终用户都能简单地通过一个URL 来访问SQL Server. 本节我们主要介绍以下三个问题: 如何创建虚拟目录 HTTP 的语法 HTTP 的访问能力 20.4.1 创建虚拟目录    在使用HTTP 访问SQL

Access 通用数据访问类(asp.net 2.0 c#)

access|asp.net|访问|数据 仿照以前收集的一个经典sql server数据访问类,稍做修改.using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;usi

数据访问接口体系及数据对象模型探讨--[附录]

对象|访问|数据|体系 数据访问接口体系及数据对象模型探讨(Beat 1.0)                                                             81_RedStar81@163.com                                               TomHornson.student@www.sina.com.cn                                                个

数据访问接口体系及数据对象模型探讨--[1]

对象|访问|数据|体系 数据访问接口体系及数据对    数据访问接口体系及数据对象模型探讨(Beat 1.0)                          81_RedStar81@163.com  TomHornson.student@www.sina.com.cn 个人文集: http://www.csdn.net/develop/author/netauthor/RedStar81/       文章索引: 预:概念 序言:回首历史 一. 数据访问接口体系探讨 1.       Op