ADO 对象编程模型:
* 引入ADO 库文件;
* 断开连接,结束。
1、引入ADO库文件
使用ADO前必须在工程的stdafx.h文件里用直接引入符号#import引入ADO库文件,以使编译器能正确编译。
#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF") rename("BOF","adoBOF")
这行语句声明在工程中使用ADO,但不使用ADO的名字空间,并且为了避免常数冲
突,将常数EOF改名为adoEOF。现在不需添加另外的头文件,就可以使用ADO接口
了。
2、初始化OLE/COM库环境
必须注意的是,ADO库是一组COM动态库,这意味应用程序在调用ADO前,必须初
始化OLE/COM库环境。在MFC应用程序里,一个比较好的方法是在应用程序主类
的InitInstance成员函数里初始化OLE/COM库环境。
//初始化OLE/COM库环境----------------------
AfxEnableControlContainer(); //这句话貌似可以省,因为我发现有的应用程序里没有
if (!AfxOleInit())
{
AfxMessageBox("初始化OLE DLL失败!");
return FALSE;
}
//---------------------------
函数AfxOleInit在每次应用程序启动时初始化OLE/COM库环境。
同DAO和CDatabase一样,ADO由几个接口组成:
_ConnectionPtr,_CommandPtr和_RecordsetPtr.
不同于DAO和Cdatabase的是,ADO基于COM的接口,因此,假如你没有接触过COM,你应该在使用ADO前先找有关书籍了解一下COM。
另外,也看到用如下方法初始化OLE环境的
(
初始化COM环境
::CoInitialize(NULL); //在app类中的InitInstance函数中添加
::CoUninitialize(); //在app类中的InitInstance函数的最后(return之前)添加,释放COM环境
3.
首先先在dlg头文件中先声明这三个智能指针,通过这些指针可以很容易的创建和删除ADO对象。
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
_CommandPtr m_pCommand;
4.创建connection对象
在第3步中,在dlg头文件中声明了 _ConnectionPtr m_pConnection;
但是,在实际情况中,我们却习惯在应用程序主类中,来声明
即在应用程序主类中,添加
_ConnectionPtr m_pConnection;
//创建connection对象
m_pConnection.CreateInstance(__uuidof(Connection));
try
{
// 打开本地Access库studentDB.mdb
//设置连接字符串("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\studentDB.mdb")(2000的在代码中有!),使 用Open方法连接数据库
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\studentDB.mdb","","",adModeUnknown);
//要注意,Data Source 这两个单词是分开来写的,且Data 前面的是分号,而不是逗号,
另外,Data Source后面是我们想connection (连接) 的数据库的全路径,不能写错了,否则肯定连不上
}
catch(_com_error& e)
{
//调用在CAdoRWAccessDlg中打印错误信息的静态函数
CTestDlg::dump_com_error(e);//
return FALSE;
}
也有这样写的:
try
{
m_pConnection.CreateInstance("ADODB.Connection");
//打开本地Access 库studentDB.mdb
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\studentDB.mdb","","",adModeUnknown);
}
catch (_com_error e)
{
AfxMessageBox("数据库连接失败,确认数据库路径是否正确!");
return FALSE;
}
若要使用dump_com_error(e)来捕获具体的连接错误,则该函数按下面的方式来写
void CTestDlg::dump_com_error(_com_error &e)
{
CString ErrorStr;
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
ErrorStr.Format( "\n\tADO Error\n\tCode = %08lx\n\tCode meaning = %s\n\tSource = %s\n\tDescription = %s\n\n",
e.Error(), e.ErrorMessage(), (LPCTSTR)bstrSource, (LPCTSTR)bstrDescription );
//在调试窗口中打印错误信息,在Release版中可用DBGView查看错误信息
::OutputDebugString((LPCTSTR)ErrorStr);
#ifdef _DEBUG
AfxMessageBox(ErrorStr, MB_OK | MB_ICONERROR);
#endif
}
5.通过以上四步,就建立起了数据库和VC应用程序的连接,在dlg类的OnInitDialog()函数中,使用ADO创建数据库记录集
// 使用ADO创建数据库记录集
m_pRecordset.CreateInstance(__uuidof(Recordset));//这是com组件里面创建对象的调用方法,对象调用CreateInstance创建,参数是全球唯一标示符
try
{
m_pRecordset->Open("SELECT * FROM STUDENT", // 查询STUDENT表中所有字段,即对表STUDENT进行操作
theApp.m_pConnection.GetInterfacePtr(), // 获取库接库的IDispatch指针
adOpenDynamic,
adLockOptimistic,
adCmdText);
}
catch(_com_error& e)
{
dump_com_error(e);
// 或者用 AfxMessageBox("不能打开记录集"); 来弹出错误
}
6.如果是通过列表控件和数据库进行操作,那么可以在OnInitDialog()再添加一些控件的初始化操作
例如:
_variant_t theValue;
if(!m_pRecordset->adoEOF)
{
//获取学号的值
theValue=m_pRecordset->GetCollect("stuID");
if(theValue.vt!=VT_NULL)
m_stuid=(char*)_bstr_t(theValue);
//获取学生姓名
theValue=m_pRecordset->GetCollect("name");
if(theValue.vt!=VT_NULL)
m_name=(char *)_bstr_t(theValue);
//获取学生年龄
theValue=m_pRecordset->GetCollect("age");
if(theValue.vt!=VT_NULL)
m_age=theValue.iVal;
//获取学生性别
theValue=m_pRecordset->GetCollect("sex");
if(theValue.vt!=VT_NULL)
m_sex=(char *)_bstr_t(theValue);
//获取学生专业
theValue=m_pRecordset->GetCollect("subject");
if(theValue.vt!=VT_NULL)
m_subject=(char *)_bstr_t(theValue);
}
UpdateData(FALSE);
7.断开连接,结束
在dlg类中在添加void ExitConnect()函数
void CMy1Dlg::ExitConnect()
{
//关闭记录集和连接
if(m_pRecordset!=NULL)
m_pRecordset->Close();
m_pConnection->Close();
}
8.总结
由于COM对象是跨平台的,它使用了一种通用的方法来处理各种类型的数据,因此CString 类和COM对象是不兼容的,我们需要一组API来转换COM对象和C++类型的数据。_vatiant_t和_bstr_t就是这样两种对象。它们提供了通用的方法转换COM对象和C++类型的数据。
数据访问发展的趋势是OLE DB.使用OLE DB最简单的方法是ADO.ADO的对象层次模型封装了数据库访问细节,为C++程序员提供了一种非常好的数据访问策略。
MFC使用ADO对象开发数据库应用程序,具体可参照下面的一篇文章:
http://www.cnblogs.com/yaowen/archive/2013/01/06/2848356.html