使用ADO 对象开发数据库应用程序 (数据库和MFC应用程序连接)

ADO 对象编程模型: 

* 引入ADO 库文件; 

 *初始化OLE/COM 库环境; 
 * 用3 个智能指针进行数据库操作,connection 对象连接数据库; 
*  利用建立好的连接,通过connection、Command 对象执行SQL 命令,并取得结果记录集; 
* 记录集的遍历、更新; 

* 断开连接,结束。 


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;

然后在InitInstance()函数中,再添加如下代码:

//创建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


Delphi TThread中文注释2009-10-22 16:58TThread是一个抽象类,可以创建几个独立的线程。 类关系 TObject 在一个多线程的应用程序中创建一个TThread的后子类代表一个线程。每一新子类的TThread对象的实例是一个新的线程。从TThread派生的多线程实例可以构成Delphi的多线程应用程序。    当一个应用程序运行时,应用程序就被载入内存准备执行。此时,它成为包含一个或多个线程的进程,每个线程含有数据、代码和系统资源。线程执行应用程序的部分内容,并由系统分配CPU时间。同一进程的所有线程共享同一地址空间,可以访问进程的全局变量。线程通过以下工作改善应用的性能:管理多通信设备的输入。    区分任务的优先级。优先级高的处理紧急的任务。优先级低的处理其他任务。    以下是使用线程的一些建议:    同时跟踪太多的线程消耗CPU时间。对单处理器系统,一个进程最多有16个线程。    当多个线程更新相同的资源时,应使线程同步以避免冲突。    大多数访问VCL对象和更新窗体的方法必须从主VCL线程内部调用。    以下为创建和使用一个新线程的过程:    (1)单击File|New|Thread菜单项,创建一个包含对象的新单元,该对象源于TThread类。    (2)定义新线程对象和Create方法。    (3)通过插入线程执行时需要的代码定义线程对象和Execute方法。    (4)将使用VCL组件的任何调用传递给Synchronize方法,以避免多线程冲突。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值