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

 /************************************************************************/
/* 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. Android UI:机智的远程动态更新策略

    问题描述 做过Android开发的人都遇到过这样的问题:随着需求的变化,某些入口界面通常会出现 UI的增加.减少.内容变化.以及跳转界面发生变化等问题.每次发生变化都要手动修改代码,而入口界面通常具有 ...

  2. logstahs 匹配isslog

    2016-11-30 06:33:33 192.168.5.116 GET /Hotel/HotelDisplay/cncqcqb230 - 80 - 192.168.9.2 Mozilla/5.0+ ...

  3. 【HDOJ】2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

    多重背包. #include <stdio.h> #include <string.h> ]; int n, m; void completePac(int p, int h) ...

  4. bzoj1179

    这种tarjan+dp的水题我竟然还WA了两次,要小心! type link=^node;      node=record        po:longint;        next:link; ...

  5. (转载)AS3领航系列教程 之 AS3程序的入口

    (转载)http://blog.csdn.net/wibrst/article/details/1861828 要实践本教程, 您需要安装以下软件:    Flash CS3 AS3程序的入口 众所周 ...

  6. Java正则表达式应用总结

    http://lavasoft.blog.51cto.com/ http://lavasoft.blog.51cto.com/62575/179324      Java正则表达式应用总结   一.概 ...

  7. Modifying the ASP.NET Request Queue Limit

    Modifying the ASP.NET Request Queue Limit When ASP.NET is queried, the request for service is carrie ...

  8. SDPLR的安装过程(matlab)

    SDPLR 半正定规划优化工具的安装过程很简单,只要按照SDPLR 1.03-beta User's Guide (short version).pdf的介绍安装就可以. 运行在下载的工具包目录里运行 ...

  9. Poj 3695-Rectangles 矩形切割

    Rectangles Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3846   Accepted: 1124 Descri ...

  10. dell vfoglight

    vFoglight针对RH/Vmware/Hyper-v/Vsphere环境的相关软件包下载链接 https://software.dell.com/register/getfile/?param=2 ...