C++数据库操作并生成ini文件。

 

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值