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

 /************************************************************************/
/* INSTRUCTION: 封装ADO数据库相关操作
DETAILS: 只能在MFC下使用,因此使用了MFC的字符串类
尝试进行了深度封装,但是很多选项(如存储过程)被屏蔽了,适合小型项目使用。
NOTE: ADO数据库访问并不是线程安全的,多个线程公用一个Connection需要线程同步,推荐方法
是每个线程用一个单独的Connection,因此这里没有写成单例模式
*/
/************************************************************************/
#pragma once #include <comdef.h>
#include <list>
#include <set>
#include <string>
#include <boost\lexical_cast.hpp> #import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF") class AdoRecordReader;
class CAdoController
{
public: CAdoController(void)
{
AfxOleInit();
}
~CAdoController(); enum DatabaseProviderEnum
{
Access2000,
ODBC,
Oracle,
SqlServer,
}; bool init();
//连接数据库
bool Connect(const std::string connectstring);
bool Connect(DatabaseProviderEnum database,std::string dataSource,
std::string ip,std::string username,std::string psw); //是否连接成功
bool IsConnected()const
{
return (bool)m_pConnection->State;
} //非SELECT命令,返回影响的行数
int ExecuteNonQuery(const std::string& command); //SELECT命令,返回封装的_RecordSetPtr
AdoRecordReader ExecuteReader(const std::string& command); //TODO:存储过程,待实现
//_RecordsetPtr ExecuteStoreProceduce(const std::string& storeProceduceName); private:
std::string connectStringBuilder( DatabaseProviderEnum database,
std::string &ip, std::string dataSource,
std::string username, std::string psw ); _ConnectionPtr m_pConnection;
_CommandPtr m_pCommand;
_RecordsetPtr m_pRecordset;
}; /*
* _RecordSetPtr相关函数封装,只读实现,不考虑ADO离线层
*/
class AdoRecordReader
{
public:
explicit AdoRecordReader(_RecordsetPtr ptr):
m_recordSetPtr(ptr)
{ }
//使其引用计数+1
AdoRecordReader(const AdoRecordReader& lhs)
{
m_recordSetPtr=lhs.m_recordSetPtr->Clone(adLockOptimistic);
} //减少引用计数
~AdoRecordReader()
{
if (m_recordSetPtr->State)
{
m_recordSetPtr->Close();
m_recordSetPtr.Release();
}
} //移动至下一条记录
bool MoveNext()
{
HRESULT hr;
hr=m_recordSetPtr->MoveNext(); if (!SUCCEEDED(hr))
{
return false;
}
if (m_recordSetPtr->adoEOF)
{
return false;
}
return true;
}
//移动到第一条记录
void MoveFirst()
{
m_recordSetPtr->MoveFirst();
}
//重载下标访问操作符(索引和列名),注意这里下标访问也是只读的
_variant_t operator[](const size_t index)const;
_variant_t operator[](const std::string key)const; //强类型get函数,使用模板来进行强制类型转换
template<typename T>
T get(const size_t index)const
{
return boost::lexical_cast<T>(this->operator[](index));
}
template<typename T>
T get(const std::string key)const
{
return boost::lexical_cast<T>(this->operator[](key));
} //字符串特化
template<>
std::string get<std::string>(const size_t index)const
{
return std::string((char *)(_bstr_t)(this->operator[](index)));
} template<>
std::string get<std::string>(const std::string key)const
{
return std::string((char *)(_bstr_t)(this->operator[](key)));
} //行数
int RecordCount()
{
return m_recordSetPtr->RecordCount;
}
//列数
int FieldCount()
{
return m_recordSetPtr->Fields->Count;
}
private:
_RecordsetPtr m_recordSetPtr;
};
 #include "AdoController.h"
#include <iostream>
#include <stdexcept>
#include <boost\algorithm\string.hpp> CAdoController::~CAdoController(void)
{
if (m_pConnection->State)
{
m_pConnection->Close();
}
m_pCommand.Release();
m_pRecordset.Release();
m_pConnection.Release();
} bool CAdoController::init()
{
HRESULT hr; hr=m_pConnection.CreateInstance("ADODB.Connection");
if (!SUCCEEDED(hr))
{
return false;
} hr=m_pCommand.CreateInstance("ADODB.Command");
if (!SUCCEEDED(hr))
{
return false;
} hr=m_pRecordset.CreateInstance("ADODB.Recordset");
if (!SUCCEEDED(hr))
{
return false;
} return true;
} bool CAdoController::Connect( DatabaseProviderEnum database, std::string dataSource,
std::string ip,std::string username,std::string psw)
{
if (m_pConnection->State)
{
m_pConnection->Close();
}
std::string connectstring = connectStringBuilder(database, ip, dataSource, username, psw);
return Connect(connectstring);
} bool CAdoController::Connect( const std::string connectstring )
{
HRESULT hr;
try
{
hr=m_pConnection->Open(_bstr_t(connectstring.c_str()),"","",adModeUnknown);
if (!SUCCEEDED(hr))
{
throw std::exception();
}
return true;
}
catch(_com_error e)
{
std::cerr<<"连接数据库失败!"<<std::endl
<<e.Description()<<std::endl;
return false;
}
} std::string CAdoController::connectStringBuilder( DatabaseProviderEnum database,
std::string &ip, std::string dataSource,
std::string username, std::string psw )
{
std::string connectstring;
switch (database)
{
case CAdoController::Access2000:
connectstring+="Provider=Microsoft.Jet.OLEDB.4.0;DataSource=";
if (ip.length()!=)
{
connectstring+="\\\\"+ip+"\\"+dataSource+";";
}
else
{
connectstring+=dataSource+";";
}
connectstring+=username+";";
connectstring+=psw+";";
break;
case CAdoController::ODBC:
//FIXIT: 远程连接字符串待添加
connectstring+="Provider=MADASQL;DSN="+dataSource+";UID="+
username+";PWD="+psw+";";
break;
case CAdoController::Oracle:
//FIXIT: 远程连接字符串待添加
connectstring+="Provider=MSDAORA;DataSource="+dataSource+";User ID="+
username+";Password="+psw+";";
break;
case CAdoController::SqlServer:
if (username!="")
{
connectstring+="Provider=SQLOLEDB;DataSource="+ip+";Initial Catalog="+
dataSource+";UserID="+username+";Password="+psw+";";
}
else
{
connectstring+="Provider=SQLOLEDB;DataSource=.;Initial Catalog="+
dataSource+";Integrated Security=SSPI;";
}
break;
default:
break;
}
return connectstring;
} int CAdoController::ExecuteNonQuery( const std::string& command )
{
if(boost::istarts_with(command,"select"))
{
throw std::exception("SELECT command queried, you should use ExecuteReader Instead!");
return ;
}
if (!m_pConnection->State)
{
throw std::exception("数据库连接尚未打开");
return ;
}
_variant_t effectLineCount=;
m_pConnection->Execute(_bstr_t(command.c_str()),&effectLineCount,adCmdText); return (int)effectLineCount;
} //执行查询命令,注意这里会抛出异常
AdoRecordReader CAdoController::ExecuteReader( const std::string& command )
{
if (!boost::istarts_with(command,"select"))
{
throw std::exception("Non SELECT command executed, you should user ExecuteNonQuery instead");
}
if (!m_pConnection->State)
{
std::cerr<<"数据库连接尚未打开"<<std::endl;
throw std::exception("数据库未打开");
} _variant_t conn=_variant_t((IDispatch *)m_pConnection,true); try
{
if (m_pRecordset->State)
{
m_pRecordset->Close();
}
m_pRecordset->Open(_variant_t(command.c_str()),conn,adOpenStatic,
adLockOptimistic,adCmdText);
return AdoRecordReader(m_pRecordset);
}
catch(_com_error e)
{
std::cerr<<e.Description()<<std::endl;
throw std::exception("查询出现错误");
}
} _variant_t AdoRecordReader::operator[]( const size_t index ) const
{
try
{
return m_recordSetPtr->GetCollect(_variant_t((long)index));
}
catch(_com_error e)
{
std::cerr<<e.Description()<<std::endl;
return NULL;
}
} _variant_t AdoRecordReader::operator[]( const std::string key ) const
{
try
{
return m_recordSetPtr->GetCollect(_variant_t(key.c_str()));
}
catch(_com_error e)
{
std::cerr<<e.Description()<<std::endl;
return NULL;
}
}

ADO简单封装(MFC)的更多相关文章

  1. .net core 中简单封装Dapper.Extensions 并使用sqlsuger自动生成实体类

    引言 由公司需要使用dapper  同时支持多数据库 又需要支持实体类 又需要支持sql 还需要支持事务 所以采用了 dapper + dapperExtensions  并配套 生成实体类小工具的方 ...

  2. 学习:简单使用MFC创建对话框窗口

    MFC介绍:微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows ...

  3. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

  4. FMDB简单封装和使用

    工具:火狐浏览器+SQLite Manager插件 ; Xcode; FMDB库; 效果: 项目地址: https://github.com/sven713/PackFMDB 主要参考这两篇博客: 1 ...

  5. Android--Retrofit+RxJava的简单封装(三)

    1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...

  6. okhttp3 get post 简单封装

    最近打算在新项目中使用 okhttp3, 简单封装了一下异步 get post 因为 CallBack 也是在子线程中执行,所以用到了 Handler public class MyOkHttpCli ...

  7. python网页请求urllib2模块简单封装代码

    这篇文章主要分享一个python网页请求模块urllib2模块的简单封装代码. 原文转自:http://www.jbxue.com/article/16585.html 对python网页请求模块ur ...

  8. 对pymysql的简单封装

    #coding=utf-8 #!/usr/bin/python import pymysql class MYSQL: """ 对pymysql的简单封装 "& ...

  9. iOS开发——UI篇OC篇&UITableView简单封装

    UITableView简单封装 UITableView时iOS开发中使用最多也是最重的一个UI空间,其实在App Store里面的%80以上的应用都用到了这个控件,所以就给大家介绍一下,前面的文章中也 ...

随机推荐

  1. OA学习笔记-007-Dao层设计

    一. User, UserDao save(User user), update(), delete(), find(), ...Role, RoleDao save(Role role), upda ...

  2. css全局设置

      /***** 全局设置 *****/ body,h1,h2,h3,h4,h5,h6,p,form,ul,ol,li,dt,dl,dd,th,td,label,bottom,input,textar ...

  3. windows桌面添加右键环境

    1.组合键win + R,输入regedit,回车   打开注册表编辑器 2.找到目录中[HKEY_CLASSES_ROOT\Directory\Background\shell]对其右键,新建一个项 ...

  4. 【转】windows7 64位系统认不出8g内存显示只有3G可用

    原文网址:http://www.jb51.neos/windows/93721.html   我的电脑安装的是Win7 64位系统,当时内存是用的8G的,系统里面显示出来只有3.00G可用,真是崩溃啊 ...

  5. 【转】Android开发之旅:环境搭建及HelloWorld

    原文网址: http://www.cnblogs.com/skynet/archive/2010/04/12/1709892.html 引言 本系列适合0基础的人员,因为我就是从0开始的,此系列记录我 ...

  6. 给Apache加载rewrite模块后,服务器返回500错误,以及a2enmod命令

    我的机子是Ubuntu. 今天想给url做一个rewrite,让url看起来更漂亮一点.在Apache配置文件(我的是 /etc/apache/apache2.conf)文件中已经把AllOverri ...

  7. loadrunner 与Md5

    loadrunner 与Md5 1.新建个c vuser脚本 2.把cmd5.h导入脚本 3.在脚本中,引入cmd5.h,可以在action前面加个void,但要屏蔽return 来自为知笔记(Wiz ...

  8. yml文件数据的简洁表达方法(Hashes to OpenStruct)

    通过ruby编写测试脚本的时候,我还是喜欢采用yml来管理测试数据,就像以前的文章(Selenium WebDriver + Grid2 + RSpec之旅(五))提到的一样,但是在引用yml中的数据 ...

  9. Nido.Common.Utilities.MD5类

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Sec ...

  10. leetcode 二分查找

    https://oj.leetcode.com/problems/search-for-a-range/就是一个二分查找,没事练练手 public class Solution { public in ...