【MFC】数据库操作——ADO(21)

ActiveX Data Objects (ADO) 通过 OLE DB 访问和操作数据库,OLE DB是一组”组件对象模型”(COM) 接口,封装了ODBC的功能。相比MFC封装的ODBC类,使用ADO可以对数据库进行更高效、更灵活访问。

实现步骤(以SQL SERVER为例)

1、安装数据库,设置访问用户和密码,新建数据库和数据表

 

 关于SQL SERVER安装和使用可以参考相关文档。

2、在MFC中使用ADO

首先,引入ADO库文件

在stdafx.h (预编译头文件),或者自建的ADO类头文件中添加代码:

#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF")

然后,在使用ADO 前,初始化OLE/COM库环境,

CoInitialize(NULL);

初始化 _ConnectionPtr  _RecordsetPtr 和 _CommandPtr 三个接口,调用相应的功能实现数据库访问(前面两个接口就可以完成数据库的大部分操作)。

优点:

MFC的ODBC类绑定每张表,意味着新建一张表就需要创建一个记录集类来访问;而ADO利用_RecordsetPtr (_CommandPtr )执行SQL语句来实现数据库的CURD操作。

缺点:

ADO相对来说比较复杂,尤其是COM中使用的VARIANT和BSTR数据类型 , 以及和他们相应的两个类 _variant_t  、_bstr_t 。

3、实现

新建类 CAdoSqlServer 

头文件

#pragma once
#import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
#include <vector>
using namespace std;
class CAdoSqlServer
{
private:
	_ConnectionPtr m_Connection;
	 _RecordsetPtr m_DataSet;
	 bool isInit;
	 CAdoSqlServer(void);
	 ~CAdoSqlServer(void);	
public:	
	static CAdoSqlServer* GetInstance()
	{
		static CAdoSqlServer m_sinstance;
		return &m_sinstance;
	}
	bool Init(CString serverName,CString dataBaseName,CString useName,CString passWord,CString &errStr);
	void Select(CString sql,vector<vector<CString> > &resultVector);
};

其中设计思路:使用单例模式对数据库访问、通过Init函数配置数据库信息、数据表的查询直接返回二维的向量vector (第一行是数据表字段,后续行是记录)

CPP文件

#include "stdafx.h"
#include "AdoSqlServer.h"

//CAdoSqlServer* CAdoSqlServer::pInstance=NULL;
CAdoSqlServer::CAdoSqlServer(void):isInit(false),m_Connection(NULL),m_DataSet(NULL)
{
	 CoInitialize(NULL);
}


CAdoSqlServer::~CAdoSqlServer(void)
{
	CoUninitialize();
}
bool CAdoSqlServer::Init(CString serverName,CString dataBaseName,CString useName,CString passWord,CString &errStr)
{
	if(m_Connection==NULL  && FAILED(m_Connection.CreateInstance("ADODB.Connection")))
	{
		errStr = TEXT("ADODB.Connection Init error");
		return false;
	}
	if(m_DataSet==NULL && FAILED(m_DataSet.CreateInstance("ADODB.Recordset")))
    {
		errStr = TEXT("ADODB.Recordset Init error");
		return false;
	}
	
	CString strSRC;
	strSRC="Driver=SQL Server;Server=";
	strSRC+=serverName;
	strSRC+=";Database=";
	strSRC+=dataBaseName;
	strSRC+=";UID=";
	strSRC+=useName;
	strSRC+=";PWD=";
	strSRC+=passWord;
	_bstr_t bstrSRC(strSRC);
	if (FAILED(m_Connection->Open(bstrSRC,"","",-1)))
	{
		errStr = TEXT("Can not open Database!");
		return false;
	}	
	return isInit = true;
}
void CAdoSqlServer::Select(CString sql,vector<vector<CString> > &resultVector)
{
	m_DataSet->Open(sql.GetBuffer(0),m_Connection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdUnknown);
	FieldsPtr ft;
	ft = m_DataSet->Fields;
	vector<_bstr_t> th;
	vector<CString> tmp;
	_bstr_t bs;
	for(int i=0; i< ft->GetCount();i++)                 
	{        
		CString tmpStr;
	    bs =ft->GetItem(_variant_t((long)i))->Name;
		th.push_back(bs);
		tmpStr=(LPCSTR)(bs);
		tmp.push_back(tmpStr);
	}   
	int s;
	if((s=th.size()) == 0) return;
	resultVector.push_back(tmp);
	while(!m_DataSet->adoEOF)                 
	{     
		tmp.clear();
		for(int i=0;i<s;i++)                      
		{                  
			if(m_DataSet->GetCollect(th[i]).vt !=VT_NULL)                           
			{ 
				CString tmpStr;
			    bs = m_DataSet->GetCollect(th[i]);	
				tmpStr=(LPCSTR)(bs);
		        tmp.push_back(tmpStr);
			}    
			else tmp.push_back(TEXT(""));
		}  
		resultVector.push_back(tmp);
		m_DataSet->MoveNext(); 		            
	}       
}

字符串的  L  和 TEXT 可以通过设置工程属性为多字节来省略。

 该类的使用相对来说比较容易,示例代码:

    CAdoSqlServer* instance=CAdoSqlServer::GetInstance();
	CString cs=L"";
	instance->Init(TEXT("******"),TEXT("******"),TEXT("******"),TEXT("******"),cs);
    //填入信息:服务器名、数据库、用户名、密码
	//此处可以通过cs来获取连接中是否有错误

    vector<vector<CString> > resultVector;
	instance->Select(L"select top 10 * from TagsTable",resultVector);
    // SQL语句
    //返回查询集,包含表头,简单粗暴!

猜你喜欢

转载自blog.csdn.net/yixiaobo2001/article/details/129125622