我最近在学习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()当然在调用其他所有的数据库中的类。