分享
 
 
 

VC数据库编程分析

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

作者: 胡朝晖

我们知道,在VB下进行基于ADO的编程相对比较简单,只要我们通过reference加载了适当的类型库以后,我们就可以正常的调用ADO对象,但是可能很多开发人员对于VC下的基于ADO,OLE DB的数据库开发就没有很多经验了。所以我们有必要先讨论一下VC下基于ADO开发的几种模式。

VC下关于ADO的操作分析

一般来说,用VC++有三种方法可以实现对ADO的操作:

1. 通过#import方法

2. 通过利用MFC OLE的ClassWizard

3. 通过Windows API中COM相关的函数

在所有这三种方法种,#import是最方便的方法,它允许你产生一个类似VB的类结构。使你的开发变的很方便。

#import方法

在#import中,你需要提供所包含的类型库的路径和名称,它能够自动产生一个对GUIDs的定义,同时对自动生成对ADO对象的封装。同时,能够列举它在类型库中所能找到的类型,对任何你所引用的类型库,VC++会在编译的时候自动生成两个文件:

一个头文件(.tlh),它包含了列举的类型和对类型库中对象的定义

一个实现文件(.tli)对类型库对象模型中的方法产生封装。

比如,你在stdafx.h文件中增加对msado15.dd的import以后,VC++会产生msado15.tlh和msado15.tli两个文件。

#import也能够使用一个新的类,_com_ptr_t,也被称为智能指针。智能指针能够自动执行QuyerInterface,AddRef和Release函数。对一个COM对象模型使用#import产生代码和VBA很类似。

下面的代码演示了如何使用#import在你的应用中实现对ADO的操作:

#import "c:\program files\common files\system\ado\msado15.dll"

no_namespace

rename ( "EOF", "adoEOF" )

对EOF进行该名是必要的,因为典型的VC++应用都已经定义了EOF作为常数-1。

下面分析用#import定义和初始化ADO对象

通常来说,操作一个自动化对象需要两个步骤:定义和初始化一个用来操作COM对象的变量。通过#import你可以在一行代码完成这个工作,通过使用智能指针(_com_ptr_t)的构造函数传递一个有效的CLSID或者是PROGID。开发人员也可以通过_com_ptr_t::CreateInstance()方法来定义对象的一个示例。具体代码如下所示:

_ConnectionPtr Conn1( __uuidof( Connection ) );

也可以采用下面的代码实现同样的功能

_ConnectionPtr Conn1 = NULL; file://定义对象

HRESULT hr = S_OK;

hr = Conn1.CreateInstance( __uuidof( Connection ) ); file://创建实例

推荐采用第二种方法,因为如果用第一种方法的话不能返回一个失败的HRESULT,所以也就不能判断ADO连接对象是成功还是失败。注意这里的__uuidof( Connection)中的Connection是在.tlh文件中定义的。通过把它传递给方法CreateInstance,实际上就是创建了一个有效的ADOConnection对象。

需要注意到的是#import中有一个属性为no_namespace,这是告诉编译器该类不在一个单独的名字空间中,使用no_namespace意味着你不需要在初始化变量的时候引用名字空间。当然如果在你的应用中需要倒入多个类型库的话,最后不要使用no_namespace,以免引起名字冲突。

下面是简单的基于ADO应用的代码,采用了#import方法:

#include

#import rename("EOF", "adoEOF")

void main()

{

HRESULT hr = S_OK;

file://因为没有在#import中指定no_namespace,所以必须采用ADODB::这样的形式

file://来作为变量类型

ADODB::_RecordsetPtr Rs1 = NULL;

file://通过ODBC建立ADO连接

_bstr_t Connect( "DSN=AdoDemo;UID=sa;PWD=;" );

_bstr_t Source ( "SELECT * FROM Authors" );

CoInitialize();

file://初始化Rs1对象

hr = Rs1.CreateInstance( __uuidof( ADODB::Recordset ) );

file://对hr的返回正确性判断省略

Rs1->Open( Source, Connect,

ADODB::adOpenForwardOnly,

ADODB::adLockReadOnly, -1 );

file://这里可以对记录集Rs1进行操作

Rs1->Close();

Rs1 = NULL;

::MessageBox( NULL, "Success!", "", MB_OK );

CoUninitialize();

}

用MFC OLE创建ADO应用

MFC OLE类似于#import,能够对一个类型库产生一个封装(wrapper),但是不象#import,MFC OLE不能够从类型库中产生枚举类型,但是它能够更干净的实现ADO。MFC类CString和COleVariant隐藏了BSTRS和Variants的细节。需要注意的是,有MFC OLE产生的类封装都是继承了类ColeDispatchDriver,由ADO产生的失败的HRESULTS被封装在类ColeDispatchException中。

首先我们需要说明一下用MFC OLE ClassWizard创建ADO应用的几个不可缺少的步骤:

从Tools菜单中,选择Options,然后选择Directories tab,在Show Directories中,选择Library Files,然后在directories增加路径C:\program files\common files\system\ado,这样做的目的是设置包含ADO类型库的路径。

从View菜单中,选择ClassWizard,点击Add Class按纽并选择From A Type Library...,然后在Type Library dialog box对话框中,从C:\program files\common files\system\ado选择文件msado15.dll,在Confirm Classes对话框中,选择所有列出的类并按OK按纽,退出ClassWizard。实际上,ClassWizard为你生成了两个文件msado15.h和msado15.cpp.

下面的代码是实现ADO应用的自己编写的代码:

AfxOleInit(); file://初始化COM对象

...

_Recordset Rs1; file://定义数据集对象

COleException e;

COleVariant Connect( "DSN=AdoDemo;UID=sa;PWD=;" );

COleVariant Source ( "SELECT * FROM Authors" );

file://创建数据集对象

Rs1.CreateDispatch( "ADODB.Recordset.2.0", &e );

Rs1.Open( (VARIANT) Source, (VARIANT) Connect, 0, 1, -1 );

file://这里可以对结果集Rs1进行处理

Rs1.Close();

Rs1.ReleaseDispatch();

AfxMessageBox("Success!");

#import和MFC OLE都围绕着一个给定的自动化对象产生了一个封装类,它们分别继承自_com_ptr_t和ColeDispatchDriver。但是事实上,你可以通过使用Windows API函数直接初始化ADO对象,下面讨论直接用Win32 API函数来操作COM对象。

用COM API创建ADO工程

为了直接使用ADO和COM对象,需要添加两个头文件adoid.h和adoint.h,这两个头文件定义了CLSIDs,接口定义和你操作ADO类型库所需要的枚举类型。同时你也需要增加头文件INITGUID.H。

为了能够编译用COM API创建的ADO工程文件,你需要安装OLE DB SDK或者是MSDASDK工具。下面是简单的示例代码:

#include

#include

#include "adoid.h" // ADO的GUID’s

#include "adoint.h" // ADO的类、枚举等等

void main()

{

HRESULT hr = S_OK;

ADORecordset* Rs1 = NULL; // ADORecordset 是在adoint.h中定义的

VARIANT Source;

VARIANT Connect;

VariantInit( &Source );

VariantInit( &Connect );

Source.vt = VT_BSTR;

Source.bstrVal = ::SysAllocString( L"SELECT * FROM Authors");

Connect.vt = VT_BSTR;

Connect.bstrVal = ::SysAllocString( L"DSN=AdoDemo;UID=sa;PWD=;" );

hr = CoCreateInstance( CLSID_CADORecordset,

NULL,

CLSCTX_INPROC_SERVER,

IID_IADORecordset,

(LPVOID *) &Rs1 );

if( SUCCEEDED( hr ) ) hr = Rs1->Open( Source,

Connect,

adOpenForwardOnly,

adLockReadOnly,

-1 );

file://这里你可以对记录集Rs1进行处理

if( SUCCEEDED( hr ) ) hr = Rs1->Close();

if( SUCCEEDED( hr ) ) { Rs1->Release(); Rs1 = NULL; }

if( SUCCEEDED( hr ) ) ::MessageBox( NULL, "Success!", "", MB_OK );

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有