我最近在学习C++,刚学了半个月吧,带我的导师就开始让我写一个利用c++来开发个工具,这可难坏我了,起初以为根本弄不出来。但是经过不停的修改,导师的带领最终还是弄出来了。明白做技术的在不懈的努力下,肯定会把结果弄出来的。
这是一个头文件,有实现的
#pragma once
#include "DBAccessor.h"
#include <vector>
using namespace std;
#include "..\Public\MFCSupport.h"
#include "../Public/Tools/CriticalSection.h"
class CModularDB
{
private:
static CModularDB m_instanceDBModular; // 类的静态实例指针
CModularDB(void);
~CModularDB(void);
public:
static CModularDB* GetInstance();
int Init(CString p_strAppPath);
void Free();
CDBAccessor* CreateAccessor();
void FreeAccessor(CDBAccessor* p_pAccessor);
private:
vector<CDBAccessor*> m_vtrAccessor;
CString m_strAppPath;
CriticalSection m_csLock;
};
下面是实现文件。#include "ModularDB.h"
#include "ADOAccessor.h"
#include "..\Public\Tools\AutoLock.h"
CModularDB CModularDB::m_instanceDBModular;
CModularDB* CModularDB::GetInstance()
{
return &m_instanceDBModular;
}
CModularDB::CModularDB(void)
{
m_strAppPath = _T("");
}
CModularDB::~CModularDB(void)
{
Free();
}
int CModularDB::Init(CString p_strAppPath)
{
HRESULT l_hResult = ::CoInitialize(NULL);
if(FAILED(l_hResult))
{
return 999;
}
m_strAppPath = p_strAppPath;
return 0;
}
void CModularDB::Free()
{
Lock l(m_csLock);
for(size_t i = 0; m_vtrAccessor.size() > i; i++)
{
CDBAccessor* l_pAccessor = NULL;
l_pAccessor = m_vtrAccessor.at(i);
if(NULL != l_pAccessor)
{
delete l_pAccessor;
}
}
m_vtrAccessor.clear();
::CoUninitialize();
}
CDBAccessor* CModularDB::CreateAccessor()
{
CADOAccessor* l_pAccessor = NULL;
try
{
Lock l(m_csLock);
l_pAccessor = new CADOAccessor();
if(0 != l_pAccessor->Init())
{
throw 1;
}
m_vtrAccessor.push_back(l_pAccessor);
}
catch(...)
{
// 记错误日志;
if(NULL != l_pAccessor)
{
delete l_pAccessor;
l_pAccessor = NULL;
}
}
return l_pAccessor;
}
void CModularDB::FreeAccessor(CDBAccessor* p_pAccessor)
{
if(NULL == p_pAccessor)
{
return;
}
Lock l(m_csLock);
vector<CDBAccessor*>::iterator l_itAccessor = m_vtrAccessor.begin();
for(; m_vtrAccessor.end() != l_itAccessor; l_itAccessor++)
{
CDBAccessor* l_pAccessor = *l_itAccessor;
if(l_pAccessor == p_pAccessor)
{
delete l_pAccessor;
m_vtrAccessor.erase(l_itAccessor);
return;
}
}
}
上边的两个文件主要实现了数据库驱动的加载还有就是连接。下面的主要是数据库操作的一些基本方法。
/*############################################################################
【文件名】: ADOAccessor.h
【名 称】: ADO 封装类.
【作 者】: cxsc
---------------------------------------------------------
【创建时间】: 2007-06-25
【修改时间】: 2007-06-29
#############################################################################*/
#if !defined(_ADOACCESSOR_H_)
#define _ADOACCESSOR_H_
#if _MSC_VER > 1000
#pragma once
#endif
// 导入 ado 库 ----------------------------------------------------------------
#pragma warning(disable:4146)
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" named_guids rename("EOF","adoEOF"), rename("BOF","adoBOF")
//#include "ADOAccessor.h"
#pragma warning(default:4146)
using namespace ADODB;
#include <icrsint.h>
#include "DBAccessor.h"
#include "../Public/Tools/CriticalSection.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 错误报告宏
//-----------------------------------------------------------------------------
#if !defined CATCH_ERROR
#define CATCH_ERROR \
{ \
CString strComError; \
strComError.Format("错误编号: %08lx\n错误信息: %s\n错误源: %s\n错误描述: %s", \
e.Error(), \
e.ErrorMessage(), \
(LPCTSTR) e.Source(), \
(LPCTSTR) e.Description()); \
/*::MessageBox(NULL,strComError,L"错误",MB_ICONEXCLAMATION);*/ \
}
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 数据库操作类
//-----------------------------------------------------------------------------
class CADOAccessor : public CDBAccessor
{
public:
CADOAccessor(void);
~CADOAccessor(void);
int Init();
int OpenDataBase(const char* p_pInitStr);
int ExecuteSQL(const char* p_pSQL);
void* GetRecordset(const char* p_pSQL); //待改进
_RecordsetPtr GetRecordsetEx(const char* p_pSQL); //
protected:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset; //
private:
//CriticalSection m_csLock;
};
//-----------------------------------------------------------------------------
#endif // _ADOACCESSOR_H_
下面是实现文件。
#include "..\Public\MFCSupport.h"
#include "ADOAccessor.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
/*#########################################################################
------------------------------------------------
数据库操作类
------------------------------------------------
#########################################################################*/
/
// Constructor / Destructor
/
CADOAccessor::CADOAccessor(void)
{
}
//----------------------------------------------------------------------
CADOAccessor::~CADOAccessor(void)
{
try
{
if(m_pConnection->State & adStateOpen)//连接状态下,要把数据库关闭
{
m_pConnection->Close();
}
}
catch(_com_error e)
{
// 记错误日志
}
}
int CADOAccessor::Init()
{
HRESULT l_hResult = ::CoInitialize(NULL);
if(FAILED(l_hResult))
{
return -1;
}
// 创建 Connection 对象
m_pConnection.CreateInstance("ADODB.Connection");
if(NULL == m_pConnection)
{
return 1;
}
return 0;
}
/*****************************************************************************
* 打开数据库
* p_pInitStr : [in], 数据库全路径名
*
* 返回值: -1:先前以被打开 0;打开失败 1:打开成功
*
*****************************************************************************/
int CADOAccessor::OpenDataBase(const char* p_pInitStr)
{
try
{
if(NULL == m_pConnection)
{
return 1;
}
if(m_pConnection->State & adStateOpen)
{
return 2;
}
_bstr_t l_bstrConnect(p_pInitStr);
// 连接数据库
if(S_OK != m_pConnection->Open(l_bstrConnect, "", "", adConnectUnspecified))
{
return 3;
}
}
catch(_com_error e)
{
// 记错误日志
CString strError;
strError.Format( "警告:打开数据库表时发生异常,错误信息:%s , %s ,%s",
(LPCSTR)e.Source() ,e.ErrorMessage() , (LPCSTR)e.Description());
return -1;
}
return 0;
}
/*****************************************************************************
* 执行无返回值得SQL语句
* p_pSQL : [in], 要执行的SQL语句
*
*****************************************************************************/
int CADOAccessor::ExecuteSQL(const char* p_pSQL)
{
CString strSQL = _T("");//_T()怎么个情况?
strSQL.Format(_T("%s"), p_pSQL);
ASSERT(m_pConnection != NULL);
ASSERT(AfxIsValidString(strSQL));
try
{
_bstr_t l_btSQL(strSQL.GetBuffer());
m_pConnection->Execute(l_btSQL, NULL, adCmdText);
}
catch (_com_error e)
{
TRACE(_T("Warning: Execute 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
CATCH_ERROR;
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
TRACE(_T("Source:%s; Description:%s;"), bstrSource, bstrDescription);
return -1;
}
catch(...)
{
return -2;
}
return 0;
}
/*****************************************************************************
* 执行查询,返回查询记录集
* lpszSQL : [in], 要执行的SQL语句
* lOptions : [in], 指示 strSQL 参数的类型,缺省为命令文本
*****************************************************************************/
void* CADOAccessor::GetRecordset(const char* p_pSQL)
{
CString strSQL = _T("");
strSQL.Format(_T("%s"), p_pSQL);
ASSERT(m_pConnection != NULL);
ASSERT(AfxIsValidString(strSQL));
try
{
_bstr_t l_btSQL(strSQL.GetBuffer());
m_pRecordset = m_pConnection->Execute(l_btSQL, NULL, adCmdText);
void* l_pReturn = reinterpret_cast<void*>(&m_pRecordset);
return l_pReturn;
}
catch (_com_error e)
{
TRACE(_T("Warning: Execute 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
CATCH_ERROR;
return NULL;
}
return NULL;
}
//------------------------------------------------------------------------------------
_RecordsetPtr CADOAccessor::GetRecordsetEx(const char* p_pSQL)
{
CString strSQL = _T("");
strSQL.Format(_T("%s"), p_pSQL);
ASSERT(m_pConnection != NULL);
ASSERT(AfxIsValidString(strSQL));
try
{
_bstr_t l_btSQL(strSQL.GetBuffer());
return m_pRecordset = m_pConnection->Execute(l_btSQL, NULL, adCmdText);
}
catch (_com_error e)
{
TRACE(_T("Warning: Execute 方法发生异常. 错误信息: %s; 文件: %s; 行: %d\n"), e.ErrorMessage(), __FILE__, __LINE__);
CATCH_ERROR;
return NULL;
}
return NULL;
}
上边的两个文件主要是数据库操作的基本类和方法。
下边主要是实体类
#pragma once
#include "..\..\Public\DataEngine\SmartDE.h"
#include "..\..\Database\ADOAccessor.h"
#include <map>
using namespace std;
struct data{
string commandID;
string handSetNO;
string returnCode;
string explain;
string list;
data()
{
commandID="";
handSetNO="";
explain="";
list="";
}
};
struct sInfoDB
{
int iFlag; // 0:读数据库,返回记录集;1:操作数据库,不返回记录集;
CString strSQL;
CString strDB;
CADOAccessor* pAccessor;
_RecordsetPtr pRecordset;
sInfoDB()
{
iFlag = 0;
strSQL = _T("");
strDB = _T("数据库路径");
pAccessor = NULL;
pRecordset = NULL;
}
};
class GetData
{
public :
GetData(void){}
virtual ~GetData(void){}
vector<data> getdata();
data g_data;
int OperateDB(sInfoDB& p_sDB);
void FreeDB(sInfoDB& p_sDB);
int makeini(vector<data> data);
CSmartDE* m_pInDE;
CSmartDE* m_pOutDE;
CString m_strPathApp;
CString m_strFileDB;
int VariantT2string(variant_t p_vtValue, string& p_strValue);
CADOAccessor* OpenDB(CString p_strPathDB); // p_strPathDB:数据库文件名、全路径
public:
virtual void SetDE(CSmartDE* p_pInDE, CSmartDE* p_pOutDE)
{
m_pInDE = p_pInDE;
m_pOutDE = p_pOutDE;
}
};
下面就是实现类了。
// createini.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "createini.h"
#include "..\..\Database\ModularDB.h"
#include <iostream>
#include<fstream>
using namespace std;
从数据库中取数据,将其放到vector<data> 中。
vector<data> GetData::getdata()
{
CADOAccessor* l_pAccessor = NULL;
_RecordsetPtr l_pRecordset = NULL;
sInfoDB l_sDB;
l_pAccessor = OpenDB("E:/2011年06月全省版本/Config/Config(1).mdb");
ASSERT(l_pAccessor);
CString l_strSQL = _T("");
l_strSQL.Format("SELECT CommandID,HandsetNo,ReturnCode,Explain,List FROM ResponseData order by CommandID");
l_pRecordset = l_pAccessor->GetRecordsetEx(l_strSQL);
ASSERT(l_pRecordset);
vector<data> vtrList;
//map<string, vector<data>> l_mapData;
while(!l_pRecordset->adoEOF)
{
//vector<data> vtrList;
variant_t l_vtValue;
data d;
l_vtValue = l_pRecordset->GetCollect("CommandID");
VariantT2string(l_vtValue, d.commandID);
l_vtValue = l_pRecordset->GetCollect("HandsetNo");
VariantT2string(l_vtValue, d.handSetNO);
l_vtValue = l_pRecordset->GetCollect("ReturnCode");
VariantT2string(l_vtValue, d.returnCode);
l_vtValue = l_pRecordset->GetCollect("Explain");
VariantT2string(l_vtValue, d.explain);
l_vtValue = l_pRecordset->GetCollect("List");
VariantT2string(l_vtValue, d.list);
vtrList.push_back(d);
l_pRecordset->MoveNext();
//l_mapData[d.commandID] = vtrList;
}
return vtrList;
}
///***
//取出数据,讲数据放入生成ini文件中。
//先取出每个对象d,然后对commandID判断,如果相同则放入同一个文件
// 如果不相同,则重新生成一个ini文件中
int GetData:: makeini(vector<data> s_data)
{
string s_commandid;
string s_handSetNO;
string s_explain;
string s_returncode;
string s_list;
for(vector<data> ::iterator iter=s_data.begin();iter!=s_data.end();++iter)
{
s_commandid=(*iter).commandID;
s_handSetNO=(*iter).handSetNO;
s_returncode=(*iter).returnCode;
s_explain=(*iter).explain;
s_list=(*iter).list;
static string temp;
if(temp==s_commandid)
{
string l_strFile ="e:\\file\\";
string t_strFile=".ini";
l_strFile+= temp;
//char* path="e:\\1.ini";
//t_strFile+=l_strFile;
l_strFile+=t_strFile; ///e:\file\0100.ini
char* path=(char*)l_strFile.c_str();
//char* path = "E:\\file\\1.ini"; // 你要创建文件的路径
ofstream fout(path,ios::app | ios::out);
//fout.seekp(ios::end);
if(fout)
{
fout<<s_handSetNO<<"="<<s_returncode<<"~"<<s_explain<<";"<<s_list<<endl;
fout.close();
}
}
else
{
temp=s_commandid;
string l_strFile ="e:\\file\\";
string t_strFile=".ini";
l_strFile+= (string)(*iter).commandID;
//char* path="e:\\1.ini";
//t_strFile+=l_strFile;
l_strFile+=t_strFile; ///e:\file\0100.ini
char* path=(char*)l_strFile.c_str();
//char* path = "E:\\file\\1.ini"; // 你要创建文件的路径
ofstream fout(path);
if(fout)
{
fout<<s_handSetNO<<"="<<s_returncode<<"~"<<s_explain<<";"<<s_list<<endl;
fout.close();
}
}
}
return 0;
}
int GetData::VariantT2string(variant_t p_vtValue, string& p_strValue)
{
if(VT_BSTR != p_vtValue.vt)
{
p_strValue.clear();
return 1;
}
CString l_strValue = p_vtValue;
p_strValue = l_strValue.GetBuffer();
return 0;
}
CADOAccessor* GetData::OpenDB(CString p_strPathDB)
{
int l_iReturn = 0;
CADOAccessor* l_pAccessor = NULL;
try
{
l_pAccessor = reinterpret_cast<CADOAccessor*>(CModularDB::GetInstance()->CreateAccessor());
ASSERT(l_pAccessor);
CString l_strFileDB = _T("");
//l_strFileDB.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s..\..\Config\Config.mdb");
l_strFileDB.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s", p_strPathDB);
if(0 != l_pAccessor->OpenDataBase(l_strFileDB))
{
l_iReturn = 1;
throw l_iReturn;
}
}
catch(...)
{
if(NULL != l_pAccessor)
{
CModularDB::GetInstance()->FreeAccessor(l_pAccessor);
l_pAccessor = NULL;
}
}
return l_pAccessor;
}
int GetData::OperateDB(sInfoDB& p_sDB)
{
try
{
CString l_strDB = _T("");
l_strDB.Format("%s/%s", this->m_strPathApp.GetBuffer(), p_sDB.strDB.GetBuffer());
p_sDB.pAccessor = OpenDB(l_strDB);
p_sDB.pRecordset = p_sDB.pAccessor->GetRecordsetEx(p_sDB.strSQL);
}
catch(...)
{
return -1;
}
return 0;
}
void GetData::FreeDB(sInfoDB& p_sDB)
{
if(NULL != p_sDB.pAccessor)
{
CModularDB::GetInstance()->FreeAccessor(p_sDB.pAccessor);
p_sDB.pAccessor = NULL;
}
}
由于本项目是在一个mfc工程里建的,然后直接就将调用的方法放到了createini2Dlg.cpp内了。
// TODO: 在此添加额外的初始化代码***************************************?//华丽的分割线。
GetData data;
data.makeini(data.getdata());
主要是这些了。
下面主要是讲解一下改程序 主要运行过程吧。首先在入口处直接调用 类GetData内部的方法,既makeini方法,其主要作用就是取出数据,讲数据放入生成ini文件中。
//先取出每个对象d,然后对commandID判断,如果相同则放入同一个文件
// 如果不相同,则重新生成一个ini文件中
然后起参数就是getData方法了,他返回了数据库中的所有的记录。
从数据库中取数据,将其放到vector<data> 中。
vector<data> GetData::getdata()
getdata()当然在调用其他所有的数据库中的类。