学习实践:使用模式,原则实现一个C++数据库访问类
/** @brief 数据库操作异常 */ class HI_DB_EXPORT HiDBException { public: HiDBException(); public: std::string ToSrting(); public: std::string m_sql; /**< 本次操作的SQL语句 */ std::string m_descript; /**< 异常描述 */ std::string m_position; /**< 异常位置 */ long m_errorId; /**< 异常编号 */ HiDBType m_dbTyp; /**< 数据库类型 */ };
/** @brief 异常语句宏 */ #define HiDBHelperOnError(ps, script,sql, id) HiDBException exception;exception.m_position = ps;exception.m_descript = script;exception.m_sql = sql;exception.m_errorId = id;throw exception;//return false;
/** @brief 数据库类型 */ enum HiDBType { HiDBType_Invail, /**< 无效类型 */ HiDBType_MySQL, /**< MySQL */ }; 构造函数的声明就明确下来了: /** * @brief 构造函数 * @param[in] type 数据库类型 * @param[in] isUsingLock 是否需要使用互斥锁 */ HiDB(HiDBType type = HiDBType_MySQL, bool isUsingLock = false); <2>打开数据库连接 打开数据库连接比较简单: /** * @brief 打开数据库连接 * @param[in] conn 数据库连接字符串 * @retval true:成功,false;失败 * @par 实例: * @code * HiDB db; * if (db.Open("host=127.0.0.1;port=3306;dbname=test;user=root;pwd=root;charset=gbk;")) * { * // 打开成功 * } * else * { * // 打开失败 * } * @endcode */ bool Open(const char* conn) throw (HiDBException);
/** * @brief 关闭据库连接 */ void Close(void);
/** * @brief 数据库连接是否打开 */ bool IsOpen();
/** * @brief 执行SQL语句,并不返回结果 * @param[in] conn SQL语句 * @retval true:成功,false;失败 * @par 实例: * @code * HiDB db; * if (db.ExecuteNoQuery("UPDATE table SET Paramer1=‘%s‘ * and Paramer2=‘%s‘ OR Paramer3=%d", "test1", "test2", 3)) * { * // 执行成功 * } * else * { * // 执行失败 * } * @endcode */ bool ExecuteNoQuery(const char* sql, ...) throw (HiDBException);
/** * @brief 执行SQL语句,返回一个结果 * @param[in] sql SQL语句 * @retval 获得的数据,如果为空,则失败 */ std::string ExecuteScalar(const char* sql, ...) throw (HiDBException);
#ifndef HiDBTable typedef std::map<std::string, std::string> HiDBMap; /** @brief 查询结果 */ typedef std::vector<HiDBMap> HiDBTable; /**< 查询结果 */ #endif
/** * @brief 执行SQL语句,返回一个结果集合 * @param[in] sql SQL语句 * @retval 存储查询记录的智能指针 */ std::shared_ptr<HiDBTable> ExecuteQuery(const char* sql, ...) throw (HiDBException);
/** * @brief 在事务中执行处理 * @param[in] fun 处理函数 */ void OnTransaction(const std::function<void()>& fun) throw (HiDBException);
HiDB m_DB = new HiDB(HiDBType_MySQL, true); try { bool ret = m_DB->Open( "host=127.0.0.1;port=3306;dbname=test;user=root;pwd=root;charset=gbk;" ); m_DB->ExecuteNoQuery("drop table if exists table1;"); string val = m_DB->ExecuteScalar( "SELECT column4 FROM table1 WHERE column1=‘%s‘ AND column3=%d", &val, "hitest", 59); shared_ptr<HiDBTable> table = this->m_DB->ExecuteQuery( "SELECT * FROM table1 WHERE column1=‘%s‘ OR column1=‘%s‘", "hitest", "mytest"); } catch(HiDBException& e) { // ... }
#pragma once /** * @defgroup 数据库模块 * @{ */ #include "HiDBExport.h" #include <string> #include <vector> #include <map> #include <sstream> /** @brief 数据库类型 */ enum HiDBType { HiDBType_Invail, /**< 无效类型 */ HiDBType_MySQL, /**< MySQL */ }; #ifndef HiDBTable typedef std::map<std::string, std::string> HiDBMap; /** @brief 查询结果 */ typedef std::vector<HiDBMap> HiDBTable; /**< 查询结果 */ #endif /** @brief 数据库操作异常 */ class HI_DB_EXPORT HiDBException { public: HiDBException(); public: std::string ToSrting(); public: std::string m_sql; /**< 本次操作的SQL语句 */ std::string m_descript; /**< 异常描述 */ std::string m_position; /**< 异常位置 */ long m_errorId; /**< 异常编号 */ HiDBType m_dbTyp; /**< 数据库类型 */ }; /** @brief 异常语句宏 */ #define HiDBHelperOnError(ps, script,sql, id) HiDBException exception;exception.m_position = ps;exception.m_descript = script;exception.m_sql = sql;exception.m_errorId = id;throw exception;//return false; /**//** @}*/ // 数据库模块
#pragma once /** * @defgroup 数据库模块 * @{ */ #include <memory> #include <functional> #include "HiDBCommon.h" class HiDBImpl; #pragma warning (disable: 4290) /** * @brief 数据库操作类,封装数据库的通用操作,本类使用策略模式实现 * @author 徐敏荣 * @date 2012-06-14 * * @par 修订历史 * @version v0.5 \n * @author 徐敏荣 * @date 2012-06-14 * @li 初始版本 * @version v0.6 \n * @author 徐敏荣 * @date 2014-08-04 * @li 简化程序 * */ class HI_DB_EXPORT HiDB { public: /** * @brief 构造函数 * @param[in] type 数据库类型 * @param[in] isUsingLock 是否需要使用互斥锁 */ HiDB(HiDBType type = HiDBType_MySQL, bool isUsingLock = false); /** * @brief 析构函数 */ ~HiDB(); public: /** * @brief 打开数据库连接 * @param[in] conn 数据库连接字符串 * @retval true:成功,false;失败 * @par 实例: * @code * HiDB db; * if (db.Open("host=127.0.0.1;port=3306;dbname=test;user=root;pwd=root;charset=gbk;")) * { * // 打开成功 * } * else * { * // 打开失败 * } * @endcode */ bool Open(const char* conn) throw (HiDBException); /** * @brief 关闭据库连接 */ void Close(void); /** * @brief 数据库连接是否打开 */ bool IsOpen(); public: /** * @brief 执行SQL语句,并不返回结果 * @param[in] conn SQL语句 * @retval true:成功,false;失败 * @par 实例: * @code * HiDB db; * if (db.ExecuteNoQuery("UPDATE table SET Paramer1=‘%s‘ * and Paramer2=‘%s‘ OR Paramer3=%d", "test1", "test2", 3)) * { * // 执行成功 * } * else * { * // 执行失败 * } * @endcode */ bool ExecuteNoQuery(const char* sql, ...) throw (HiDBException); public: /** * @brief 执行SQL语句,返回一个结果 * @param[in] sql SQL语句 * @retval 获得的数据,如果为空,则失败 */ std::string ExecuteScalar(const char* sql, ...) throw (HiDBException); public: /** * @brief 执行SQL语句,返回一个结果集合 * @param[in] sql SQL语句 * @retval 存储查询记录的智能指针 */ std::shared_ptr<HiDBTable> ExecuteQuery(const char* sql, ...) throw (HiDBException); public: /** * @brief 在事务中执行处理 * @param[in] fun 处理函数 */ void OnTransaction(const std::function<void()>& fun) throw (HiDBException); private: /** * @brief 数据库操作实现指针 */ HiDBImpl* m_Impl; /**< 数据库操作实现指针 */ }; /**//** @}*/ // 数据库模块
#if !defined(HISDB_ON_VARLIST) #define HISDB_ON_VARLIST(x, y) char chArr[2048] = {0};char* pchar = &chArr[0];va_list pArgList;va_start(pArgList, y);::_vsnprintf(chArr, 2047, x, pArgList); va_end(pArgList) ; #endif
/** * @brief 临界区访问类,主要封装windows临界区的访问,该类主要在栈中使用,利用局部变量的构造和析构函数出入临界区 * @author 徐敏荣 * @date 2012-06-14 * * @par 修订历史 * @version v0.5 \n * @author 徐敏荣 * @date 2012-06-14 * @li 初始版本 * */ class HiCritical { public: /** * @brief 构造函数 */ HiCritical() { ::InitializeCriticalSection(&cs); } /** * @brief 析构函数 */ ~HiCritical() { ::DeleteCriticalSection(&cs); } /** * @brief 进入临界区 */ void Enter() { ::EnterCriticalSection(&cs); } /** * @brief 离开临界区 */ void Leave() { ::LeaveCriticalSection(&cs); } CRITICAL_SECTION* GetSection() { return &cs; } private: /** * @brief 临界区对象 */ CRITICAL_SECTION cs; /**< 临界区对象 */ };
/** * @brief 临界区访问管理类,利用构造函数进入临界区,利用西沟函数离开临界区 * 如果向构造函数提供NULL参数,则不使用临界区。 * */ class HiCriticalMng { public: HiCriticalMng(HiCritical& crl): cl(&crl) { cl->Enter(); } HiCriticalMng(HiCritical* crl): cl(crl) { if (cl) { cl->Enter(); } } ~HiCriticalMng() { if (cl) { cl->Leave(); } } private: HiCritical* cl; };
#pragma once /** * @defgroup 数据库操作实现类接口类 * @brief 数据库操作实现类接口类,声明数据库操作实现类的接口。 * @author 徐敏荣 * @date 2012-06-14 * * @par 修订历史 * @version v0.5 \n * @author 徐敏荣 * @date 2012-06-14 * @li 初始版本 * @{ */ #include "DB/HiDB.h" class HiCritical; /** * @brief 数据库操作实现类接口类,声明数据库操作实现类的接口 * */ class HiDBImpl { public: /** * @brief 构造函数 * @param[in] isUsingLock 是否需要使用互斥锁 */ HiDBImpl(bool isUsingLock); /** * @brief 析构函数 */ virtual ~HiDBImpl(); public: /** * @brief 打开数据库连接 * @param[in] conn 数据库连接字符串 * @retval true:成功,false;失败 */ virtual bool Open(const char* conn) = 0; /** * @brief 关闭据库连接 */ virtual void Close(void) = 0; public: /** * @brief 执行SQL语句,并不返回结果 * @param[in] conn SQL语句 * @retval true:成功,false;失败 */ virtual bool ExecuteNoQuery(const char* sql) = 0; public: /** * @brief 执行SQL语句,返回一个结果 * @param[in] sql SQL语句 * @param[out] value 取得的结果 * @retval true:成功,false;失败 */ virtual std::string ExecuteScalar(const char* sql) = 0; public: /** * @brief 执行SQL语句,返回一个结果集合 * @param[in] sql SQL语句 * @param[out] table 取得的结果集合 * @retval true:成功,false;失败 */ virtual std::shared_ptr<HiDBTable> ExecuteQuery(const char* sql) = 0; public: /** * @brief 事物处理 * @retval true:成功,false;失败 */ virtual void OnTransaction(const std::function<void()>& fun) = 0; protected: /** * @brief 临界区对象,为空表示不需要考虑资源并发访问 */ HiCritical* m_pCritical; }; /**//** @}*/ // 数据库操作实现类接口类
#include <stdarg.h> #include "DB/HiDB.h" #include "HiDBMySQL.h" using namespace std; #if !defined(HISDB_ON_VARLIST) #define HISDB_ON_VARLIST(x, y) char chArr[2048] = {0};char* pchar = &chArr[0];va_list pArgList;va_start(pArgList, y);::_vsnprintf(chArr, 2047, x, pArgList); va_end(pArgList) ; #endif static bool IsImplOK(HiDBImpl* db) { if (!db) { return false; } /* if (!db->IsOpen()) { return false; }*/ return true; } // 构造函数 HiDB::HiDB(HiDBType type, bool isUsingLock):m_Impl(NULL) { if (type == HiDBType_MySQL) { this->m_Impl = new HiDBMySQL(isUsingLock); } } // 析构函数 HiDB::~HiDB() { if (this->m_Impl) { delete this->m_Impl; this->m_Impl = NULL; } } // 打开数据库连接 bool HiDB::Open(const char* conn) { if (!this->m_Impl) { return false; } return this->m_Impl->Open(conn); } bool HiDB::IsOpen() { if (!this->m_Impl) { return false; } return true;//this->m_Impl->IsOpen(); } void HiDB::Close(void) { if (!IsImplOK(this->m_Impl)) { return; } return this->m_Impl->Close(); } bool HiDB::ExecuteNoQuery(const char* sql, ...) { if (!IsImplOK(this->m_Impl)) { return false; } HISDB_ON_VARLIST(sql, sql); return this->m_Impl->ExecuteNoQuery(chArr); } string HiDB::ExecuteScalar(const char* sql, ...) { if (!IsImplOK(this->m_Impl)) { return ""; } HISDB_ON_VARLIST(sql, sql); return this->m_Impl->ExecuteScalar(chArr); } std::shared_ptr<HiDBTable> HiDB::ExecuteQuery(const char* sql, ...) { if (!IsImplOK(this->m_Impl)) { return NULL; } HISDB_ON_VARLIST(sql, sql); return this->m_Impl->ExecuteQuery(chArr); } void HiDB::OnTransaction(const std::function<void()>& fun) { if (!IsImplOK(this->m_Impl)) { HiDBHelperOnError("HiDB::OnTransaction", "HiDB is not impl", "", 0); } return this->m_Impl->OnTransaction(fun); }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。