在VC中使用ADO开发数据库应用程序

一、ADO概述
ADO 是Microsoft为最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于使用的应用程序层接口。ADO 使您能够编写应用程序以通过 OLE.DB 提供者访问和操作数据库服务器中的数据。ADO 最主要的优点是易于使用、速度快、内存支出少和磁盘遗迹小。ADO 在关键的应用方案中使用最少的网络流量,并且在前端和数据源之间使用最少的层数,所有这些都是为了提供轻量、高性能的接口。之所以称为 ADO,是用了一个比较熟悉的暗喻,OLE 自动化接口。
OLE DB 是一组”组件对象模型”(COM) 接口,是新的数据库低层接口,它封装了ODBC的功能,并以统一的方式访问存储在不同信息源中的数据。OLE DB是Microsoft UDA(Universal Data Access)策略的技术基础。OLE DB 为任何数据源提供了高性能的访问,这些数据源包括关系和非关系数据库、电子邮件和文件系统、文本和图形、自定义业务对象等等。也就是说,OLE DB 并不局限于 ISAM、Jet 甚至关系数据源,它能够处理任何类型的数据,而不考虑它们的格式和存储方法。在实际应用中,这种多样性意味着可以访问驻留在 Excel 电子数据表、文本文件、电子邮件/目录服务甚至邮件服务器,诸如 Microsoft Exchange 中的数据。但是,OLE DB 应用程序编程接口的目的是为各种应用程序提供最佳的功能,它并不符合简单化的要求。您需要的API 应该是一座连接应用程序和 OLE DB 的桥梁,这就是 ActiveX Data Objects (ADO)。
二、在VC中使用ADO
1 、引入ADO库文件
使用ADO前必须在工程的stdafx.h文件里用直接引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下所示:
代码1:用#import引入ADO库文件
#import "c:filesfiles.dll"
no_namespaces rename("EOF" adoEOF")
这行语句声明在工程中使用ADO,但不使用ADO的名字空间,并且为了避免常数冲突,将常数EOF改名为adoEOF。现在不需添加另外的头文件,就可以使用ADO接口了。
2 、初始化OLE/COM库环境
必须注意的是,ADO库是一组COM动态库,这意味应用程序在调用ADO前,必须初始化OLE/COM库环境。在MFC应用程序里,一个比较好的方法是在应用程序主类的InitInstance成员函数里初始化OLE/COM库环境。
 
代码2:初始化OLE/COM库环境
BOOL CADOApp ::InitInstance()
{
     if(!AfxOleInit())
     {
         AfxMessageBox( “OLE初始化出错!”);
         return FALSE;
     }
     ……
}
函数AfxOleInit在每次应用程序启动时初始化OLE/COM库环境。
同DAO和CDatabase一样,ADO由几个接口组成:
_ConnectionPtr,_CommandPtr 和_RecordsetPtr.
不同于DAO和Cdatabase的是,ADO基于COM的接口,因此,假如你没有接触过COM,你应该在使用ADO前先找有关书籍了解一下COM。
3 、ADO接口简介
ADO 库包含三个基本接口:_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口。
_ConnectionPtr 接口返回一个记录集或一个空指针。通常使用它来创建一个数据连接或执行 一条不返回任何结果的SQL语句,如一个存储过程。使用_ConnectionPtr接口返回一个记录集不是一个好的使用方法。通常同CDatabase 一样,使用它创建一个数据连接,然后使用其它对象执行数据输入输出操作。
_CommandPtr 接口返回一个记录集。它提供了一种简单的方法来执行返回记录集的存储过程和 SQL语句。在使用_CommandPtr接口时,你可以利用全局_ConnectionPtr接口,也可以在_CommandPtr接口里直接使用连接串。如果你只执行一次或几次数据访问操作,后者是比较好的选择。但如果你要频繁访问数据库,并要返回很多记录集,那么,你应该使用全局 _ConnectionPtr接口创建一个数据连接,然后使用_CommandPtr接口执行存储过程和SQL语句。
_RecordsetPtr 是一个记录集对象。与以上两种对象相比,它对记录集提供了更多的控制功 能,如记录锁定,游标控制等。同_CommandPtr接口一样,它不一定要使用一个已经创建的数据连接,可以用一个连接串代替连接指针赋给 _RecordsetPtr的connection成员变量,让它自己创建数据连接。如果你要使用多个记录集,最好的方法是同Command对象一样使用 已经创建了数据连接的全局_ConnectionPtr接口,然后使用_RecordsetPtr执行存储过程和SQL语句。
 
4 、使用_ConnectionPtr接口
_ConnectionPtr 是一个连接接口,它类似于CDatabase和 CDaoDatabase。它们的工作原理相似。首先创建一个_ConnectionPtr接口实例,接着指向并打开一个ODBC数据源或OLE DB数据提供者(Provider)。以下代码和CDaoDatabase分别创建一个基于DSN和非DSN的数据连接。
 
代码3:使用CDaoDatabase(基于DSN)
CDaoDatabase MyDb = new CDaoDatabase();
MyDb.Open(NULL,FALSE,FALSE,"ODBC;DSN=samp;UID=admin;PWD=admin");
 
 
代码4:使用CDaoDatabase(基于非DSN)
CDaoDatabase MyDb = new CDaoDatabase();
MyDb.Open(NULL,FALSE,FALSE,"ODBC;DRIVER={SQL Server};SERVER=server;
DATABASE=samp;UID=admin;PWD=admin");
 
 
代码5:使用_ConnectionPtr(基于DSN)
_ConnectionPtr MyDb;
MyDb.CreateInstance(__uuidof(Connection));
MyDb->Open("DSN=samp;UID=admin;PWD=admin","","",-1);
 
 
代码6:使用_ConnectionPtr (基于非DSN)
_ConnectionPtr MyDb;
MyDb.CreateInstance(__uuidof(Connection));
MyDb->Open("Provider=SQLOLEDB;SERVER=server;DATABASE=samp;UID=admin;
PWD=admin","","",-1);
 
5 、使用_RecordsetPtr接口
_RecordsetPtr 接口的使用方法和CDaoDatabase类似,通过以下代码的比较,你会发现使用_RecordsetPtr接口非常简单(以下代码使用上面已经创建的数据连接):
 
代码7:使用CDaoDatabase执行SQL语句
CDaoRecordset MySet = new CDaoRecordset(MyDb);
MySet->Open(AFX_DAO_USE_DEFAULT_TYPE,"SELECT * FROM t_samp");
Now using ADO:
 
 
代码8:使用_RecordsetPtr执行SQL语句
_RecordsetPtr MySet;
MySet.CreateInstance(__uuidof(Recordset));
MySet->Open("SELECT * FROM some_table",
MyDb.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
现在我们已经有了一个数据连接和一个记录集,接下来就可以使用数据了。从以下代码可以看到,使用 ADO的_RecordsetPtr接口,就不需要象DAO那样频繁地使用大而复杂的数据结构VARIANT,并强制转换各种数据类型了,这也是ADO的 优点之一。假定程序有一个名称为m_List的的ListBox控件,下面代码我们用_RecordsetPtr接口获取记录集数据并填充这个 ListBox控件:
 
代码9:使用DAO访问数据
VARIANT * vFieldValue;
COleVariant covFieldValue;
CString Holder;
while(!MySet->IsEOF())
{
     MySet->GetFieldValue("FIELD_1", covFieldValue);
     vFieldValue = (LPVARIANT)covFieldValue;
     if(vFieldValue->vt!-VT_NULL)
     {
         Holder.Format("%s",vFieldValue->pbVal);
         m_List.AddString(Holder);
     }
     MySet.MoveNext();
}
 
代码10:使用ADO访问数据
_variant_t Holder
try
{
     while(!MySet->adoEOF)
     {
         Holder = MySet->GetCollect("FIELD_1");
         if(Holder.vt!=VT_NULL)
         m_List.AddString((char*)_bstr_t(Holder));
         MySet->MoveNext();
     }
}
catch(_com_error * e)
{
     CString Error = e->ErrorMessage();
     AfxMessageBox(e->ErrorMessage());
}
catch(...)
{
     MessageBox("ADO 发生错误!");
}
必须始终在代码中用try和catch来捕获ADO错误,否则ADO错误会使你的应用程序崩溃。当ADO发生运行时错误时(如数据库不存在),OLE DB数据提供者将自动创建一个_com_error对象,并将有关错误信息填充到这个对象的成员变量.
 
6 、使用_CommandPtr接口
_CommandPtr 接口返回一个Recordset对象,并且提供了更多的记录集控制功能,以下代码示例了使用_CommandPtr接口的方法:
 
代码11:使用_CommandPtr接口获取数据
_CommandPtr pCommand;
_RecordsetPtr MySet;
pCommand.CreateInstance(__uuidof(Command));
pCommand->ActiveConnection=MyDb;
pCommand->CommandText="select * from some_table";
pCommand->CommandType=adCmdText;
pCommand->Parameters->Refresh();
MySet=pCommand->Execute(NULL,NULL,adCmdUnknown);
_variant_t TheValue = MySet->GetCollect("FIELD_1");
CString sValue=(char*)_bstr_t(TheValue);
7 、关于数据类型转换
由于COM对象是跨平台的,它使用了一种通用的方法来处理各种类型的数据,因此CString 类和COM对象是不兼容的,我们需要一组API来转换COM对象和C++类型的数据。_vatiant_t和_bstr_t就是这样两种对象。它们提供了 通用的方法转换COM对象和C++类型的数据。
8 、小结
数据访问发展的趋势是OLE DB.使用OLE DB最简单的方法是ADO.ADO的对象层次模型封装了数据库访问细节,为C++程序员提供了一种非常好的数据访问策略
DAO 的设计思想使用一种接口来访问多种类型的数据。它在处理时使用Microsoft.Jet接口的ODBC数据源。DAO.Jet数据库服务的最独特的方面就是它有自己的查询引擎。但它的最大弱点是由于查询服务运行于本地机上,这就意味着在处理任何远程数据请求之前,必须把所有的数据都传输到本地工作站上,但在低速连接中调用大量数据时这是一个缺点。另外的一个缺点是它不“认识”Internet,DAO.Jet 服务是为单机和局域网(LAN)开发的。
ADO 和DAO的最大区别是ADO使用OLEDB接口而非ODBC作为底层数据供应者的。依靠OLEDB,ADO也能够支持对非SQL数据存储的纪录集访问,如Email和网络目录服务。OLEDB提供了比ODBC更多的灵活性和易用性。OLEDB服务的内部设计使得它能存取标准SQL类型的数据那样容易的访问非SQL数据存储。OLEDB的一个关键特性是它可以提供对描述性数据存储的处理。通过提供某种方法来描述数据存储方式,OLEDB可以对以任何格式存储的数据和以任何方法执行的查询提供访问途径。由于OLEDB并不要求所有数据存储都以表格、行和列的形式出现。所以与ODBC相比,它适用于更多的数据存储类型。
DAO (Data Access Objects) 数据访问对象是第一个面向对象的接口,它含有 Microsoft Jet 数据库引擎(由 Microsoft Access 所使用),并允许 Visual Basic 开发者通过 ODBC 象连接到其他数据库一样,直接访问到 Access 表。DAO 最适用于单系统应用程序或小范围本地分布使用,对大范围的异地并行设计显得功能不够强大。
RDO (Remote Data Objects) 远程数据对象是一个到 ODBC 的、面向对象的数据访问接口,它同易于使用的 DAO style组合在一起,提供了一个接口,形式上展示出所有 ODBC 的底层功能和灵活性。RDO 在访问 Jet 或 ISAM 数据库方面有一定的限制,而且它只能通过现存的 ODBC 驱动程序来访问关系数据库。但是,RDO 已被证明是许多 SQL Server、Oracle 以及其他大型关系数据库开发者经常选用的最佳接口。RDO 提供了用来访问存储过程和复杂结果集的更多和更复杂的对象、属性,以及方法。对异地并行设计Web数据库来说也不是十分理想。
ADO (ActiveX Data Objects)为ActiveX组件中数据库访问组件,ASP就是通过它实现对数据库的访问。ADO 是 DAO、RDO 的后继产物。ADO 2.0在功能上与 RDO 更相似,而且一般来说,在这两种模型之间有一种相似的映射关系。ADO “扩展”了 DAO 和 RDO 所使用的对象模型,这意味着它包含较少的对象、更多的属性、方法(和参数),以及事件。例如,ADO 没有与 rdoEngine 和 rdoEnvironment 对象相等同的对象,可以包含 ODBC 驱动程序管理器和 hEnv 接口。尽管事实上接口可能是通过 ODBC OLE DB 服务提供程序实现的,但目前也不能从 ADO 中创建 ODBC 数据源。ADO 是为 Microsoft最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于使用的应用程序层接口。OLE DB 为任何数据源提供了高性能的访问,这些数据源包括关系和非关系数据库、电子邮件和文件系统、文本和图形、自定义业务对象等等。ADO 在关键的 Internet 方案中使用最少的网络流量,并且在前端和数据源之间使用最少的层数,所有这些都是为了提供轻量、高性能的接口。同时 ADO 使用了与 DAO和 RDO相似的约定和特性,简化的语义使它更易于学习。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值