学习实践:使用模式,原则实现一个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);
- <>打开数据库连接
- 打开数据库连接比较简单:
- /**
- * @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", );
- 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[] = {};\
- char* pchar = &chArr[];\
- va_list pArgList;\
- va_start(pArgList, y);\
- ::_vsnprintf(chArr, , 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) = ;
- /**
- * @brief 关闭据库连接
- */
- virtual void Close(void) = ;
- public:
- /**
- * @brief 执行SQL语句,并不返回结果
- * @param[in] conn SQL语句
- * @retval true:成功,false;失败
- */
- virtual bool ExecuteNoQuery(const char* sql) = ;
- public:
- /**
- * @brief 执行SQL语句,返回一个结果
- * @param[in] sql SQL语句
- * @param[out] value 取得的结果
- * @retval true:成功,false;失败
- */
- virtual std::string ExecuteScalar(const char* sql) = ;
- public:
- /**
- * @brief 执行SQL语句,返回一个结果集合
- * @param[in] sql SQL语句
- * @param[out] table 取得的结果集合
- * @retval true:成功,false;失败
- */
- virtual std::shared_ptr<HiDBTable> ExecuteQuery(const char* sql) = ;
- public:
- /**
- * @brief 事物处理
- * @retval true:成功,false;失败
- */
- virtual void OnTransaction(const std::function<void()>& fun) = ;
- 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[] = {};\
- char* pchar = &chArr[];\
- va_list pArgList;\
- va_start(pArgList, y);\
- ::_vsnprintf(chArr, , 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", "", );
- }
- return this->m_Impl->OnTransaction(fun);
- }
学习实践:使用模式,原则实现一个C++数据库访问类的更多相关文章
- 一个通用数据库访问类(C#,SqlClient)
本文转自:http://www.7139.com/jsxy/cxsj/c/200607/114291.html使用ADO.NET时,每次数据库操作都要设置connection属性.建立connecti ...
- 学习实践:使用模式,原则实现一个C++数据库訪问类
一.概述 在我參与的多个项目中.大家使用libMySQL操作MySQL数据库,并且是源代码级复用,在多个项目中同样或相似的源代码.这种复用方式给开发带来了不便. libMySQL的使用比較麻烦.非常e ...
- 一个C#的XML数据库访问类
原文地址:http://hankjin.blog.163.com/blog/static/33731937200942915452244/ 程序中不可避免的要用到配置文件或数据,对于数据量比较小的程序 ...
- [node.js学习]为node.js写的一个操作mysql的类
不支持一个对象在不同异步中使用,模仿的php框架 speedphp中的model模块 GaryMysql.js var mysql = require('mysql'); var pool = nul ...
- C++实现一个单例模板类
单例模式在项目开发中使用得比较多,一个单例的模板类显得很有必要,避免每次都要重复定义一个单例类型 //非多线程模式下的一个单例模板类的实现 // template_singleton.h #inclu ...
- 学习实践:使用模式,原则实现一个C++自动化测试程序
个人编程中比较喜欢重构,重构能够提高自己的代码质量,使代码阅读起来也更清晰.但是重构有一个问题,就是如何保证重构后带代码实现的功能与重构前的一致,如果每次重构完成后,对此不闻不问,则会有极大的风险,如 ...
- DRY原则的一个简单实践
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://dzone.com/articles/dry-dont-repeat-yourse ...
- 编码最佳实践——Liskov替换原则
Liskov替换原则(Liskov Substitution Principle)是一组用于创建继承层次结构的指导原则.按照Liskov替换原则创建的继承层次结构中,客户端代码能够放心的使用它的任意类 ...
- 前端学习实践笔记--JavaScript深入【1】
这一年中零零散散看过几本javascript的书,回过头看之前写过的javascript学习笔记,未免有点汗颜,突出“肤浅”二字,然越深入越觉得javascript的博大精深,有种只缘身在此山中的感觉 ...
随机推荐
- linux下通过进程名查看其占用端口
linux下通过进程名查看其占用端口: 1.先查看进程pid ps -ef | grep 进程名 2.通过pid查看占用端口 netstat -nap | grep 进程pid 例:通过nginx进程 ...
- ImportError: DLL load failed: 找不到指定的模块
如果遇到错误:ImportError: DLL load failed: 找不到指定的模块出现错误原因:安装包的来源问题,也可以理解为包版本兼容问题,有的包使用官方出版,有的包使用whl文件安装 解决 ...
- mysql delete别名
有一个表的数据比较大,然后需要进行关联删除,删除的时候发现如下SQL报错:ELETE FROM test.test1 a WHERE EXISTS (SELECT 1 FROM test.test2 ...
- java TimeUnit 的使用
主要作用 时间颗粒度转换 延时 1.时间颗粒度转换 public long toMillis(long d) //转化成毫秒 public long toSeconds(long d) //转化成秒 ...
- 【Elasticsearch】Docker 安装 Elasticsearch 2.4.4 版本(高版本方式不同)
1. 下载 elasticsearch docker pull docker.elastic.co/elasticsearch/elasticsearch:6.4.3 2.启动 elasticsea ...
- 【Spring Boot】 Spring Boot 2.x 版本 CacheManager 配置方式
Spring Boot 1.X RedisCacheManager 配置方式 @Bean public CacheManager cacheManager(RedisTemplate redisTem ...
- Leetcode题目160.相交链表(简单)
题目描述 编写一个程序,找到两个单链表相交的起始节点. 如下面的两个链表: 在节点 c1 开始相交. 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = ...
- ci框架总结(一)
在进行数据库操作前一定要先初始化数据库类:$this->load->database(); 在model类中: class Myiapp_model extends CI_Model{ p ...
- 带你体验Android自定义圆形刻度罗盘 仪表盘 实现指针动态改变
带你体验Android自定义圆形刻度罗盘 仪表盘 实现指针动态改变 转 https://blog.csdn.net/qq_30993595/article/details/78915115 近期有 ...
- Android云端APP
使用HbuilderX打包APP 首先创建一个 5+APP+使用MUI项目 <!DOCTYPE html> <html> <head> <meta chars ...