zoukankan      html  css  js  c++  java
  • ADO简单封装(MFC)

    简单封装了一下,不是很严谨。

      1 /************************************************************************/
      2 /* INSTRUCTION: 封装ADO数据库相关操作
      3    DETAILS: 只能在MFC下使用,因此使用了MFC的字符串类
      4             尝试进行了深度封装,但是很多选项(如存储过程)被屏蔽了,适合小型项目使用。
      5    NOTE: ADO数据库访问并不是线程安全的,多个线程公用一个Connection需要线程同步,推荐方法
      6    是每个线程用一个单独的Connection,因此这里没有写成单例模式
      7 */
      8 /************************************************************************/
      9 #pragma once
     10 
     11 #include <comdef.h>
     12 #include <list>
     13 #include <set>
     14 #include <string>
     15 #include <boostlexical_cast.hpp>
     16 
     17 #import "c:program filescommon filessystemadomsado15.dll" no_namespace rename("EOF","adoEOF")
     18 
     19 class AdoRecordReader;
     20 class CAdoController
     21 {
     22 public:
     23 
     24     CAdoController(void)
     25     {
     26         AfxOleInit();
     27     }
     28     ~CAdoController();
     29 
     30     enum DatabaseProviderEnum
     31     {
     32         Access2000,
     33         ODBC,
     34         Oracle,
     35         SqlServer,
     36     };
     37 
     38     bool init();
     39     //连接数据库
     40     bool Connect(const std::string connectstring);
     41     bool Connect(DatabaseProviderEnum database,std::string dataSource,
     42         std::string ip,std::string username,std::string psw);
     43 
     44     //是否连接成功
     45     bool IsConnected()const
     46     {
     47         return (bool)m_pConnection->State;
     48     }
     49 
     50     //非SELECT命令,返回影响的行数
     51     int ExecuteNonQuery(const std::string&  command);
     52 
     53     //SELECT命令,返回封装的_RecordSetPtr
     54     AdoRecordReader ExecuteReader(const std::string& command);
     55 
     56     //TODO:存储过程,待实现
     57     //_RecordsetPtr ExecuteStoreProceduce(const std::string& storeProceduceName);
     58 
     59 private:
     60     std::string connectStringBuilder( DatabaseProviderEnum database, 
     61          std::string &ip, std::string dataSource,
     62         std::string username, std::string psw );
     63 
     64     _ConnectionPtr m_pConnection;
     65     _CommandPtr m_pCommand;
     66     _RecordsetPtr m_pRecordset;
     67 };
     68 
     69 /*
     70  *    _RecordSetPtr相关函数封装,只读实现,不考虑ADO离线层
     71  */
     72 class AdoRecordReader
     73 {
     74 public:
     75     explicit AdoRecordReader(_RecordsetPtr ptr):
     76         m_recordSetPtr(ptr)
     77     {
     78 
     79     }
     80     //使其引用计数+1
     81     AdoRecordReader(const AdoRecordReader& lhs)
     82     {
     83         m_recordSetPtr=lhs.m_recordSetPtr->Clone(adLockOptimistic);
     84     }
     85 
     86     //减少引用计数
     87     ~AdoRecordReader()
     88     {
     89         if (m_recordSetPtr->State)
     90         {
     91             m_recordSetPtr->Close();
     92             m_recordSetPtr.Release();
     93         }
     94     }
     95     
     96     //移动至下一条记录
     97     bool MoveNext()
     98     {
     99         HRESULT hr;
    100         hr=m_recordSetPtr->MoveNext();
    101 
    102         if (!SUCCEEDED(hr))
    103         {
    104             return false;
    105         }
    106         if (m_recordSetPtr->adoEOF)
    107         {
    108             return false;
    109         }
    110         return true;
    111     }
    112     //移动到第一条记录
    113     void MoveFirst()
    114     {
    115         m_recordSetPtr->MoveFirst();
    116     }
    117     //重载下标访问操作符(索引和列名),注意这里下标访问也是只读的
    118     _variant_t operator[](const size_t index)const;
    119     _variant_t operator[](const std::string key)const;
    120 
    121     //强类型get函数,使用模板来进行强制类型转换
    122     template<typename T>
    123     T get(const size_t index)const
    124     {
    125         return boost::lexical_cast<T>(this->operator[](index));
    126     }
    127     template<typename T>
    128     T get(const std::string key)const
    129     {
    130         return boost::lexical_cast<T>(this->operator[](key));
    131     }
    132 
    133     //字符串特化
    134     template<>
    135     std::string get<std::string>(const size_t index)const
    136     {
    137         return std::string((char *)(_bstr_t)(this->operator[](index)));
    138     }
    139 
    140     template<>
    141     std::string get<std::string>(const std::string key)const
    142     {
    143         return std::string((char *)(_bstr_t)(this->operator[](key)));
    144     }
    145 
    146     //行数
    147     int RecordCount()
    148     {
    149         return m_recordSetPtr->RecordCount;
    150     }
    151     //列数
    152     int FieldCount()
    153     {
    154         return m_recordSetPtr->Fields->Count;
    155     }
    156 private:
    157     _RecordsetPtr m_recordSetPtr;
    158 };
      1 #include "AdoController.h"
      2 #include <iostream>
      3 #include <stdexcept>
      4 #include <boostalgorithmstring.hpp>
      5 
      6 CAdoController::~CAdoController(void)
      7 {
      8     if (m_pConnection->State)
      9     {
     10         m_pConnection->Close();
     11     }
     12     m_pCommand.Release();
     13     m_pRecordset.Release();
     14     m_pConnection.Release();
     15 }
     16 
     17 bool CAdoController::init()
     18 {
     19     HRESULT hr;
     20 
     21     hr=m_pConnection.CreateInstance("ADODB.Connection");
     22     if (!SUCCEEDED(hr))
     23     {
     24         return false;
     25     }
     26 
     27     hr=m_pCommand.CreateInstance("ADODB.Command");
     28     if (!SUCCEEDED(hr))
     29     {
     30         return false;
     31     }
     32 
     33     hr=m_pRecordset.CreateInstance("ADODB.Recordset");
     34     if (!SUCCEEDED(hr))
     35     {
     36         return false;
     37     }
     38 
     39     return true;
     40 }
     41 
     42 bool CAdoController::Connect( DatabaseProviderEnum database, std::string dataSource,
     43                              std::string ip,std::string username,std::string psw)
     44 {
     45     if (m_pConnection->State)
     46     {
     47         m_pConnection->Close();
     48     }
     49     std::string connectstring = connectStringBuilder(database, ip, dataSource, username, psw);
     50     return Connect(connectstring);
     51 }
     52 
     53 bool CAdoController::Connect( const std::string connectstring )
     54 {
     55     HRESULT hr;
     56     try
     57     {
     58         hr=m_pConnection->Open(_bstr_t(connectstring.c_str()),"","",adModeUnknown);
     59         if (!SUCCEEDED(hr))
     60         {
     61             throw std::exception();
     62         }
     63         return true;
     64     }
     65     catch(_com_error e)
     66     {
     67         std::cerr<<"连接数据库失败!"<<std::endl
     68             <<e.Description()<<std::endl;
     69         return false;
     70     }
     71 }
     72 
     73 std::string CAdoController::connectStringBuilder( DatabaseProviderEnum database, 
     74                                                  std::string &ip, std::string dataSource,
     75                                                  std::string username, std::string psw )
     76 {
     77     std::string connectstring;
     78     switch (database)
     79     {
     80     case CAdoController::Access2000:
     81         connectstring+="Provider=Microsoft.Jet.OLEDB.4.0;DataSource=";
     82         if (ip.length()!=0)
     83         {
     84             connectstring+="\\"+ip+"\"+dataSource+";";
     85         }
     86         else
     87         {
     88             connectstring+=dataSource+";";
     89         }
     90         connectstring+=username+";";
     91         connectstring+=psw+";";
     92         break;
     93     case CAdoController::ODBC:
     94         //FIXIT: 远程连接字符串待添加
     95         connectstring+="Provider=MADASQL;DSN="+dataSource+";UID="+
     96             username+";PWD="+psw+";";
     97         break;
     98     case CAdoController::Oracle:
     99         //FIXIT: 远程连接字符串待添加
    100         connectstring+="Provider=MSDAORA;DataSource="+dataSource+";User ID="+
    101             username+";Password="+psw+";";
    102         break;
    103     case CAdoController::SqlServer:
    104         if (username!="")
    105         {
    106             connectstring+="Provider=SQLOLEDB;DataSource="+ip+";Initial Catalog="+
    107                 dataSource+";UserID="+username+";Password="+psw+";";
    108         }
    109         else
    110         {
    111             connectstring+="Provider=SQLOLEDB;DataSource=.;Initial Catalog="+
    112                 dataSource+";Integrated Security=SSPI;";
    113         }
    114         break;
    115     default:
    116         break;
    117     }    
    118     return connectstring;
    119 }
    120 
    121 int CAdoController::ExecuteNonQuery( const std::string& command )
    122 {
    123     if(boost::istarts_with(command,"select"))
    124     {
    125         throw std::exception("SELECT command queried, you should use ExecuteReader Instead!");
    126         return 0;
    127     }
    128     if (!m_pConnection->State)
    129     {
    130         throw std::exception("数据库连接尚未打开");
    131         return 0;
    132     }
    133     _variant_t effectLineCount=0;
    134     m_pConnection->Execute(_bstr_t(command.c_str()),&effectLineCount,adCmdText);
    135 
    136     return (int)effectLineCount;
    137 }
    138 
    139 //执行查询命令,注意这里会抛出异常
    140 AdoRecordReader CAdoController::ExecuteReader( const std::string& command )
    141 {
    142     if (!boost::istarts_with(command,"select"))
    143     {
    144         throw std::exception("Non SELECT command executed, you should user ExecuteNonQuery instead");
    145     }
    146     if (!m_pConnection->State)
    147     {
    148         std::cerr<<"数据库连接尚未打开"<<std::endl;
    149         throw std::exception("数据库未打开");
    150     }
    151 
    152     _variant_t conn=_variant_t((IDispatch *)m_pConnection,true);
    153 
    154     try
    155     {
    156         if (m_pRecordset->State)
    157         {
    158             m_pRecordset->Close();
    159         }
    160         m_pRecordset->Open(_variant_t(command.c_str()),conn,adOpenStatic,
    161             adLockOptimistic,adCmdText);
    162         return AdoRecordReader(m_pRecordset);
    163     }
    164     catch(_com_error e)
    165     {
    166         std::cerr<<e.Description()<<std::endl;
    167         throw std::exception("查询出现错误");
    168     }
    169 }
    170 
    171 _variant_t AdoRecordReader::operator[]( const size_t index ) const
    172 {
    173     try
    174     {
    175         return m_recordSetPtr->GetCollect(_variant_t((long)index));
    176     }
    177     catch(_com_error e)
    178     {
    179         std::cerr<<e.Description()<<std::endl;
    180         return NULL;
    181     }
    182 }
    183 
    184 _variant_t AdoRecordReader::operator[]( const std::string key ) const
    185 {
    186     try
    187     {
    188         return m_recordSetPtr->GetCollect(_variant_t(key.c_str()));
    189     }
    190     catch(_com_error e)
    191     {
    192         std::cerr<<e.Description()<<std::endl;
    193         return NULL;
    194     }
    195 }
  • 相关阅读:
    javaweb消息中间件——rabbitmq入门
    virtual box 桥接模式(bridge adapter)下无法获取ip(determine ip failed)的解决方法
    Apache Kylin本地启动
    git操作
    Java学习总结
    Java中同步的几种实现方式
    hibernate exception nested transactions not supported 解决方法
    vue 中解决移动端使用 js sdk 在ios 上一直报invalid signature 的问题解决
    cookie 的使用
    vue 专门为了解决修改微信标题而生的项目
  • 原文地址:https://www.cnblogs.com/livewithnorest/p/3316886.html
Copyright © 2011-2022 走看看