ADO简单封装(MFC)
简单封装了一下,不是很严谨。
/************************************************************************/
/* 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)的更多相关文章
- .net core 中简单封装Dapper.Extensions 并使用sqlsuger自动生成实体类
		
引言 由公司需要使用dapper 同时支持多数据库 又需要支持实体类 又需要支持sql 还需要支持事务 所以采用了 dapper + dapperExtensions 并配套 生成实体类小工具的方 ...
 - 学习:简单使用MFC创建对话框窗口
		
MFC介绍:微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows ...
 - Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
		
前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...
 - FMDB简单封装和使用
		
工具:火狐浏览器+SQLite Manager插件 ; Xcode; FMDB库; 效果: 项目地址: https://github.com/sven713/PackFMDB 主要参考这两篇博客: 1 ...
 - Android--Retrofit+RxJava的简单封装(三)
		
1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...
 - okhttp3 get post 简单封装
		
最近打算在新项目中使用 okhttp3, 简单封装了一下异步 get post 因为 CallBack 也是在子线程中执行,所以用到了 Handler public class MyOkHttpCli ...
 - python网页请求urllib2模块简单封装代码
		
这篇文章主要分享一个python网页请求模块urllib2模块的简单封装代码. 原文转自:http://www.jbxue.com/article/16585.html 对python网页请求模块ur ...
 - 对pymysql的简单封装
		
#coding=utf-8 #!/usr/bin/python import pymysql class MYSQL: """ 对pymysql的简单封装 "& ...
 - iOS开发——UI篇OC篇&UITableView简单封装
		
UITableView简单封装 UITableView时iOS开发中使用最多也是最重的一个UI空间,其实在App Store里面的%80以上的应用都用到了这个控件,所以就给大家介绍一下,前面的文章中也 ...
 
随机推荐
- PLSQL Developer Debug
			
如果要查看存储过程或者函数的执行过程,可以用debug的模式.PLSQL Developer提供了debug功能,以函数为例: 1. 找到你要debug的函数,然后右击—>选择“Add debu ...
 - USACO3.42American Heritage(二叉树)
			
已知中前 求后序 递归一下 有一些小细节 /* ID: shangca2 LANG: C++ TASK: heritage */ #include <iostream> #include& ...
 - oracle core 概述
			
oracle数据库系统的架构及其复杂,其提供的特性也非常的多.作为一种关系型数据库,oracle提供的基本特性: transaction concurrency read consistent 而支撑 ...
 - bzoj1179
			
这种tarjan+dp的水题我竟然还WA了两次,要小心! type link=^node; node=record po:longint; next:link; ...
 - BZOJ_1003_[ZJOI2006]_物流运输_(动态规划+最短路)
			
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1003 m个码头,从1运货到m,n天每天运,其中有一些码头在特定的天里不能使用.运货的代价:在两 ...
 - Jquery UI dialog 详解 (中文)
			
转载▼ 1 属性 1.11 autoOpen ,这个属性为true的时候dialog被调用的时候自动打开dialog窗口.当属性为false的时候,一开始隐藏窗口,知道.dialog("op ...
 - web测试方面的知识
			
web测试 软件测试体系架构设计 一.体系架构 1.C/S:客户端+服务器端,如QQ.单机版记事本.office等,所用语言:VB.C++.C.C#.JAVA.PB.D…等数组语言,C和S都是自己测, ...
 - Tomcat7.0配置
			
Tomcat7.0下载地址:http://tomcat.apache.org/download-70.cgi 选择符合自己操作系统的版本即可(本机win8-64位系统),选择如下: http://11 ...
 - 《锋利的Jquery第二版》读书笔记 第三章
			
DOM操作的分类 1.DOM Core不专属JavaScript,任何一种支持DOM的程序设计语言都可以使用它,也可以处理XML等标记语言编写出来的文档,getElementById().setAtt ...
 - HW4.27
			
public class Solution { public static void main(String[] args) { int count = 0; for(int i = 2001; i ...