任何的程序设计都离不开数据库的应用,数据库访问方式有ADO、DAO、ODBC、RDO、BDE......,正因为有这么多的数据库访问方式,往往由于数据库方式的不同其达到的功能也不同,一个大型软件项目各个模块的不同或一个开发小组各个成员掌握的数据库访问方式熟练程度的不同,都会出现一个软件项目使用几种数据库访问方式的情况。这时就会出现数据库访问方式冲突的问题。相信解决这种冲突的方法不止一种,但相信名字空间是最简单也是最容易让人一目了然的方法。
下面以VC下ADO的数据库访问方式举例。
先简单说说ADO(总结)。
在VC中使用ADO的开发步骤:
1,引入ADO库文件
在工程的stdafx.h里用#import引入ADO库文件。
#import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace rename("BOF","adoBOF") rename("EOF","adoEOF")
2, 初始化COM环境
::CoInitialize(NULL); //初始化OLE/COM库环境
::CoUninitialize(); //关闭OLE/COM库环境,释放资源
AfxOleInit();//初始化OLE/COM库环境(MFC自带的)
3,使用ADO库的三个基本接口
ADO库包含三个基本接口:_ConnectionPtr接口、_RecordsetPtr接口和_CommandPtr接口。
其分别对应Connection对象(完成应用程序对数据源的访问连接)、Recordset对象(将查询的结果以记录集的方式存储)和Command对象(对已连接的数据源进行命令操作)。
定义对象并创建对象实例:
方法一:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
_CommandPtr m_pCommand;
m_pConnection.CreateInstance(__uuidof(Connection));
m_pRecordset.CreateInstance(__uuidof(Recordset));
m_pCommand.CreateInstance(__uuidof(Command));
方法二:
_ConnectionPtr m_pConnection("ADODB.Connection");
_RecordsetPtr m_pRecordset("ADODB.Recordset");
_CommandPtr m_pCommand("ADODN.Command");
方法三:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
_CommandPtr m_pCommand;
m_pConnection.CreateInstance("ADODB.Connection");
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pCommand.CreateInstance("ADODN.Command");
这三种方法都是一样的,关键看你喜好。
分别举例简单说明一下:
Connection对象:
_ConnectionPtr m_pConnection;
m_pConnection.CreateInstance(__uuidof(Connection));
try{
// 打开本地Access库ChatLog.mdb
m_pConnection->Open ("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=ChatLog.mdb","","",adModeUnknown);
//SQL Server连接方法
_bstr_t strConnect = "Provider=SQLOLEDB; Server=billgates;Database=HrMan; uid=sa; pwd=sa;";
m_pConnection->Open(strConnect,"","",adModeUnknown);
}
catch(_com_error e){
AfxMessageBox(e.Description());
}
Recordset对象:
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance(__uuidof(Recordset));
CString sql;
sql.Format("SELECT DISTINCT name FROM table1");
try{
m_pRecordset->Open(sql.GetBuffer(sql.GetLength()),
_variant_t((IDispatch *)m_pConnection,true),
adOpenDynamic,
adLockOptimistic,
adCmdText);
}
catch(_com_error *e){
AfxMessageBox(e->ErrorMessage());
}
CString strName;
while (!m_pRecordset->adoEOF) {
strName.Format("%s",(char*)(_bstr_t)m_pRecordset->Fields->GetItem(_variant_t("Name"))->Value);
m_listbox.AddString(strName);
m_pRecordset->MoveNext();
}
Command对象:
_CommandPtr m_pCommand;
HRESULT hr = m_pCommand.CreateInstance(__uuidof(Command));
if(FAILED(hr))
{
AfxMessageBox("创建Command对象实例失败!");
}
CString strP_mailid;
_ParameterPtr param;
param=m_pCommand->CreateParameter("p_mailid",adVarChar,adParamOutput,strP_mailid.GetLength()+1,_variant_t(strP_mailid));
m_pCommand->Parameters->Append(param);
m_pCommand->ActiveConnection = m_pConnection;
m_pCommand->CommandType = adCmdStoredProc;
m_pCommand->CommandText = _bstr_t("P_MAIL_SEND");
try{
cmd->Execute(NULL,NULL,adCmdStoredProc);
}
catch (...) {
AfxMessageBox("调用存储过程P_MAIL_SEND有错!");
}
try{
strP_mailid = (char*)(_bstr_t)m_pCommand->Parameters->GetItem(_variant_t("p_mailid"))->GetValue();
}catch (...) {
strP_mailid = "";
}
m_pCommand.Detach();
以上只是简单介绍和总结,更深入的请参考具体书籍和网站。
ADO(总结)说完了,我们进入正题。
如:置身于某个开发小组中,一个大的软件已经形成,但是数据库访问方式用的是DAO或别的不是ADO的方式。现给你一个模块通过数据库接口
实现某些未完成的功能,这时就会有数据库的冲突问题。下面我们看看名字空间是怎么解决这个冲突问题的。
我们还按在VC中使用ADO的开发步骤来。
在VC中使用ADO的开发步骤(名字空间):
1,引入ADO库文件
在工程的stdafx.h里用#import引入ADO库文件。
这时往往就不是在stdafx.h里用#import引入ADO库文件了,而是在你要使用ADO访问方式的工程类的.h中引入了。
#import "C:/Program Files/Common Files/System/ado/msado15.dll" rename_namespace("ARXADO") rename("BOF","adoBOF")
rename("EOF","adoEOF")
2, 初始化COM环境
和上面一样。
3,使用ADO库的三个基本接口
Connection对象:
ARXADO::_ConnectionPtr m_pConnection;
m_pConnection.CreateInstance(__uuidof(ARXADO::Connection));
try{
// 打开本地Access库ChatLog.mdb
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=ChatLog.mdb","","",ARXADO::adModeUnknown);
//SQL Server连接方法
_bstr_t strConnect = "Provider=SQLOLEDB; Server=billgates;Database=HrMan; uid=sa; pwd=sa;";
m_pConnection->Open(strConnect,"","",ARXADO::adModeUnknown);
}
catch(_com_error e){
AfxMessageBox(e.Description());
}
Recordset对象:
ARXADO::_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance(__uuidof(ARXADO::Recordset));
CString sql;
sql.Format("SELECT DISTINCT name FROM table1");
try{
m_pRecordset->Open(sql.GetBuffer(sql.GetLength()),
_variant_t((IDispatch *)m_pConnection,true),
ARXADO::adOpenDynamic,
ARXADO::adLockOptimistic,
ARXADO::adCmdText);
}
catch(_com_error *e){
AfxMessageBox(e->ErrorMessage());
}
CString strName;
while (!m_pRecordset->adoEOF) {
strName.Format("%s",(char*)(_bstr_t)m_pRecordset->Fields->GetItem(_variant_t("Name"))->Value);
m_listbox.AddString(strName);
m_pRecordset->MoveNext();
}
Command对象:
ARXADO::_CommandPtr m_pCommand;
HRESULT hr = m_pCommand.CreateInstance(__uuidof(ARXADO::Command));
if(FAILED(hr))
{
AfxMessageBox("创建Command对象实例失败!");
}
CString strP_mailid;
ARXADO::_ParameterPtr param;
param=m_pCommand->CreateParameter("p_mailid",adVarChar,adParamOutput,strP_mailid.GetLength()+1,_variant_t(strP_mailid));
m_pCommand->Parameters->Append(param);
m_pCommand->ActiveConnection = m_pConnection;
m_pCommand->CommandType = ARXADO::adCmdStoredProc;
m_pCommand->CommandText = _bstr_t("P_MAIL_SEND");
try{
cmd->Execute(NULL,NULL,ARXADO::adCmdStoredProc);
}
catch (...) {
AfxMessageBox("调用存储过程P_MAIL_SEND有错!");
}
try{
strP_mailid = (char*)(_bstr_t)m_pCommand->Parameters->GetItem(_variant_t("p_mailid"))->GetValue();
}catch (...) {
strP_mailid = "";
}
m_pCommand.Detach();
方法很简单。却是开发中的精髓所在。
由于是个人写作,难免会有不正确或不恰当之处,敬请大家不吝赐教。
joinclear
2005-9-11