VC++学习笔记(7)——在Visual C++中使用ADO(续)
来源:互联网 发布:golang 引用c 编辑:程序博客网 时间:2024/06/06 00:36
VC中实现对ADO操作通常有三种方法: #import方法;利用MFC OLE的ClassWizard;通过Windows API中COM相关的函数。
在这三种方法中,#import是最方便的方法,它允许产生一个类似VB的类结构,使程序开发变得很方便。
下面分别介绍这三种方法。
1.#import方法
在#import方法中,需要提供所要包含的类型库的路径和名称,VC能够自动产生一个对GUIDs的定义,以及自动生成对ADO对象的封装。对任何引用的类型库,VC会在编译的时候自动生成两个文件:
头文件(.tlh):包含了所列举的类型和对类型库中对象的定义;
实现文件(.tli):对类型库对象模型中的方法产生封装。
例如,在stdafx.h文件中增加对msado15.dd的#import之后,VC会产生msado15.tlh和msado15.tli两个文件。
#import能够使用一个新的类_com_ptr_t,它也被称为智能指针。智能指针能够自动执行QuyerInterface、AddRef和Release函数。
下面的代码演示了如何使用#import在应用中实现对ADO的操作:
#import "c:/program files/common files/system/ado/msado15.dll" /no_namespace rename ( "EOF", "adoEOF" )
重命名EOF是必要的,因为典型的VC应用都已经定义了EOF作为常数-1。
通常来说,操作一个自动化对象需要定义和初始化一个用来操作的变量。可以通过使用智能指针(_com_ptr_t)的构造函数传递一个有效的CLSID或者是PROGID,也可以通过_com_ptr_t::CreateInstance()方法来定义对象。具体代码如下所示:
_ConnectionPtr Conn1( _uuidof( Connection ) );
也可以采用下面的代码实现同样的功能:
_ConnectionPtr Conn1 = NULL; //定义对象
HRESULT hr = S_OK; //创建实例
hr =Conn1.CreateInstance( _uuidof( Connection ) );
推荐采用第二种方式,因为用第一种方式不能返回一个失败的HRESULT,所以也就不能判断ADO连接对象是成功还是失败,以及失败的原因。注意这里的_uuidof( Connection)中的Connection是在.tlh文件中定义的。通过把它传递给方法CreateInstance,就可以创建一个有效的 ADOConnection对象。
需要注意的是#import的no_namespace属性,它告诉编译器该类在不在一个单独的名字空间中。使用no_namespace意味着不需要在初始化变量时引用名字空间。当然如果在应用中需要导入多个类型库时,最好不要使用 no_namespace,以免引起名字冲突。
下面是一个简单的采用了#import方法的基于ADO应用的示例代码:
#include
#import rename("EOF", "adoEOF")
void main()
{
HRESULT hr = S_OK; //因为没有在#import中指定no_namespace,所以必须采用ADODB::这样的形式来定义变量类型
ADODB::_RecordsetPtr Rs1 = NULL;
//通过ODBC建立ADO连接
_bstr_t Connect( "DSN=AdoDemo;UID=sa;PWD=;" );
_bstr_t Source ( "SELECT * FROM Authors" );
CoInitialize(); //初始化Rs1对象
hr = Rs1.CreateInstance( _uuidof( ADODB::Recordset ) ); //省略对返回值hr的判断 Rs1->Open( Source, Aonnect, ADODB::adOpenForwardOnly, ADODB::adLockReadOnly,-1 ); //此处可以添加对记录集Rs1进行操作的代码 Rs1->Close();
Rs1 = NULL;
::MessageBox( NULL,"Success!","",MB_OK );
CoUninitialize();
}
用MFC OLE创建ADO应用
MFC OLE同样能够封装(wrapper)一个类型库,但是与#import不同,它不能从类型库中产生枚举类型。MFC类CString和 COleVariant隐藏了BSTRS和Variants的细节。由MFC OLE产生的类都继承了类ColeDispatchDriver,由ADO产生的失败的HRESULTS被封装在类 ColeDispatchException中。
用MFC OLE ClassWizard创建ADO应用的步骤如下:
从Tools菜单中,选择Options选项中的Directories tab条目,在Show Directories中的Library Files中增加路径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应用的示例代码:
//初始化COM对象
AfxOleInit();
...
//定义数据集对象
_Recordset Rs1;
COleException e;
COleVariant Connect( "DSN=AdoDemo;UID=sa;PWD=;" );
COleVariant Source ( "SELECT * FROM Authors" ); //创建数据集对象 Rs1.CreateDispatch("ADODB.Recordset.2.0",&e );
Rs1.Open( (VARIANT) Source,(VARIANT) Connect,0, 1, -1 ); //此处可以添加对结果集Rs1进行处理的代码
Rs1.Close();
Rs1.ReleaseDispatch();
AfxMessageBox("Success!");
用COM API创建ADO工程
#import和MFC OLE都围绕着一个给定的自动化对象产生了一个封装类,它们分别继承自_com_ptr_t和ColeDispatchDriver。其实也可以通过使用 Windows API函数直接初始化ADO对象。为了直接使用ADO和COM对象,需要添加两个头文件adoid.h和adoint.h,这两个头文件定义了 CLSIDs、接口定义和操作ADO类型库所需要的枚举类型。此外,还需要增加头文件INITGUID.H。
为了能够编译用COM API创建的ADO工程文件,还需要在机器中安装OLE DB SDK或者是MSDASDK工具。下面是利用API创建ADO的简单的示例代码:
#include "adoid.h" // ADO的GUID's
#include "adoint.h" // ADO的类、枚举等等
void main()
{
HRESULT hr = S_OK; // ADORecordset 是在adoint.h中定义的 ADORecordset *Rs1 = NULL;
VARIANT Source;
VARIANT Connect;
VariantInit( &Source );
VariantInit( &Connect );
Source.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 ); //对记录集Rs1进行处理
if( SUCCEEDED( hr ) ) hr = Rs1->Close();
if( SUCCEEDED( hr ) )
{ Rs1->Release(); Rs1 = NULL; }
if( SUCCEEDED( hr ) )
::MessageBox( NULL, "Success!", "", MB_OK );
}
C++ Extensions
如果用C++进行ADO应用程序开发,应该使用ADO C++ Extensions。我们知道,用VB或者VBScript来操作ADO是非常方便的,但是如果使用C++或者是Java,就必须要处理类似 Variants这样的数据结构以实现和C++数据结构的转换,而这种处理无疑是所有C++开发人员都很头疼的事情。但如果使用C++ Extensions的话,ADO就不需要从数据提供者处得到列信息,而是在设计时刻使用开发人员提供的列信息。以下是一个简单的示例:
//创建和具体记录相对应的类
class CAuthor : public CADORecordBinding
{
BEGIN_ADO_BINDING(CCustomRs1)
ADO_VARIABLE_LENGTH_ENTRY4(1,adVarChar, m_szau_id, sizeof(m_szau_id), FALSE)
ADO_VARIABLE_LENGTH_ENTRY4(2, adVarChar,m_szau_fname,sizeof(m_szau_fname), FALSE)
ADO_VARIABLE_LENGTH_ENTRY4(3,adVarChar,m_szau_lname,sizeof(m_szau_lname), FALSE)
END_ADO_BINDING()
protected:
char m_szau_id[12];
char m_szau_fname[21];
char m_szau_lname[41];
};
void FetchAuthorData()
{
CAuthor author; //记录集对象
_RecordsetPtr pRs;
IADORecordBinding *piAdoRecordBinding; //获取COM对象接口指针
pRs.CreateInstance(_uuidof(Recordset)); //得到需要的记录集
pRs->Open("select au_id,au_fname,au_lname from Employees","Provider=SQLOLEDB;Data Source=sureshk1;Database=pubs;User Id=sa;Password=;", adOpenForwardOnly, adLockReadOnly,adCmdText); //查询接口IADORecordBinding
pRs->QueryInterface(_uuidof(IADORecordBinding),(LPVOID*)&piAdoRecordBinding); //绑定对象
piAdoRecordBinding->BindToRecordset(&author); //得到记录中的相关内容 while (VARIANT_FALSE == pRs->EOF)
{
printf("%s %s %s", author.m_szau_id,
author.m_szau_fname, author.m_szau_lname);
pRs->MoveNext();
} //释放对象
- VC++学习笔记(7)——在Visual C++中使用ADO(续)
- VC++学习笔记(8)——在Visual C++中使用ADO(结)
- VC++学习笔记(6)——在Visual C++中使用ADO
- 在VC中使用ADO
- 在VC中使用ADO
- 学习笔记》ADO.NET》在ADO.NET中使用DataSet
- 在Visual FoxPro中使用ADO数据源
- VC++学习笔记(9)——在VC中定义外部变量
- VC学习笔记:ADO
- VC学习笔记:ADO
- 【VS2010学习笔记】【编程实例】 (在Visual Studio中使用C++创建和使用DLL)
- 【VS2010学习笔记】【编程实例】 (在Visual Studio中使用C++创建和使用DLL)
- ADO在VC++中进行数据库编程(ZZ)
- 【VC++ 中使用ADO操作数据库学习笔记】 基础环境的设置
- 【VC++ 中使用ADO操作数据库学习笔记】_ConnectionPtr指针的基本用法
- VC++学习笔记(10)——CString在GetBuffer后使用Operation(+、-、*、/)
- 学习VC++深入浅出——ADO的使用
- 学习VC++深入浅出——ADO的使用
- VC++学习笔记(2)-------在VC工程中删除类
- VC++学习笔记(3)------- CString相关的一些问题以及LineLength()的
- VC++学习笔记(4)-------使用Regular Expression
- VC++学习笔记(5)——VC中ClassWizard的Parsing error
- VC++学习笔记(6)——在Visual C++中使用ADO
- VC++学习笔记(7)——在Visual C++中使用ADO(续)
- VC++学习笔记(8)——在Visual C++中使用ADO(结)
- 三道Java题,看看自己能不能作出来
- VC++学习笔记(9)——在VC中定义外部变量
- (转)直接通过ADO操作Access数据库——作者/徐景周
- 百度招聘实习生:网页搜索部_语法研究实习工程师(七种语
- 我的求职历程
- 啊
- 倍感焦虑,寻找工作