我的C++数据库访问库
1 概述
下面是我写的一个C++的数据库访问库,该库的目标是屏蔽掉繁琐的操作,以简单的接口,提供基本的访问数据库的功能。
2 主要接口
该库主要有如下接口:
Open:根据用户传入的连接字符串,打开数据库连接。
Close: 关闭已经打开的数据库连接。
ExecuteNoQuery:执行SQL语句(不需要返回结果的,例如添加、删除、编辑)
ExecuteScalar:执行SQL语句,返回第一行,第一列的数据。
ExecuteQuery:执行SQL查询,返回一个存储map的vector。
考虑到线程安全,还提供是否使用临界区的选择和数据库类型的选择(目前只支持MySQL)。
3 接口定义
该库位于His命名空间下,接口定义如下:
#pragma once
/**
* @defgroup 数据库操作类
* @brief 数据库操作类,封装数据库的通用操作。
* @author 徐敏荣
* @date 2012-06-14
*
* @par 修订历史
* @version v0.5 \n
* @author 徐敏荣
* @date 2012-06-14
* @li 初始版本
* @{
*/
#include "HisDBCommon.h"
namespace His
{
class HisDBImpl;
/**
* @brief 数据库操作类,封装数据库的通用操作
*
*/
class HISCOMM_EXPORT HisDB
{
public:
/**
* @brief 构造函数
* @param[in] type 数据库类型
* @param[in] isUsingLock 是否需要使用互斥锁
*/
HisDB(HisDBType type, bool isUsingLock);
/**
* @brief 析构函数
*/
~HisDB();
public:
/**
* @brief 打开数据库连接
* @param[in] conn 数据库连接字符串
* @retval true:成功,false;失败
*/
bool Open(const char* conn);
/**
* @brief 关闭据库连接
*/
void Close(void);
public:
/**
* @brief 执行SQL语句,并不返回结果
* @param[in] conn SQL语句
* @retval true:成功,false;失败
*/
bool ExecuteNoQuery(const char* sql, ...);
/**
* @brief 执行SQL语句,并不返回结果
* @param[in] sql SQL语句
* @param[in] paramers 参数集合
* @retval true:成功,false;失败
* @note SQL语句中,参数以特殊字符?代替,例如...“column='sd'”...替换为...?...
*/
bool ExecuteNoQuery(const char* sql, const vector<HisDBParamer>& paramers);
public:
/**
* @brief 执行SQL语句,返回一个结果
* @param[in] sql SQL语句
* @param[out] value 取得的结果
* @retval true:成功,false;失败
*/
bool ExecuteScalar(const char* sql, HisDBValue& value, ...);
/**
* @brief 执行SQL语句,返回一个结果(int)
* @param[in] sql SQL语句
* @param[out] value 取得的结果
* @retval true:成功,false;失败
*/
bool ExecuteScalar(const char* sql, int& value, ...);
/**
* @brief 执行SQL语句,返回一个结果(string)
* @param[in] sql SQL语句
* @param[out] value 取得的结果
* @retval true:成功,false;失败
*/
bool ExecuteScalar(const char* sql, string& value, ...);
/**
* @brief 执行SQL语句,并不返回结果
* @param[in] sql SQL语句
* @param[in] paramers 参数集合
* @param[out] value 取得的结果
* @retval true:成功,false;失败
* @note SQL语句中,参数以特殊字符?代替,例如...“column='sd'”...替换为...?...
*/
bool ExecuteScalar(const char* sql,
const vector<HisDBParamer>& paramers, HisDBValue& value);
/**
* @brief 执行SQL语句,并不返回结果(int)
* @param[in] sql SQL语句
* @param[in] paramers 参数集合
* @param[out] value 取得的结果
* @retval true:成功,false;失败
* @note SQL语句中,参数以特殊字符?代替,例如...“column='sd'”...替换为...?...
*/
bool ExecuteScalar(const char* sql,
const vector<HisDBParamer>& paramers, int& value);
/**
* @brief 执行SQL语句,并不返回结果(string)
* @param[in] sql SQL语句
* @param[in] paramers 参数集合
* @param[out] value 取得的结果
* @retval true:成功,false;失败
* @note SQL语句中,参数以特殊字符?代替,例如...“column='sd'”...替换为...?...
*/
bool ExecuteScalar(const char* sql,
const vector<HisDBParamer>& paramers, string& value);
public:
/**
* @brief 执行SQL语句,返回一个结果集合
* @param[in] sql SQL语句
* @param[out] table 取得的结果集合
* @retval true:成功,false;失败
*/
bool ExecuteQuery(const char* sql, HisDBTable** table, ...);
/**
* @brief 执行SQL语句,返回一个结果集合
* @param[in] sql SQL语句
* @param[in] paramers 参数集合
* @param[out] table 取得的结果集合
* @retval true:成功,false;失败
* @note SQL语句中,参数以特殊字符?代替,例如...“column='sd'”...替换为...?...
*/
bool ExecuteQuery(const char* sql,
HisDBTable** table, const vector<HisDBParamer>& paramers);
public:
/**
* @brief 向数据库中添加一条记录
* @param[in] tableName 数据库表名称
* @param[in] paramers 参数集合
* @retval true:成功,false;失败
* @note 自动根据表名、参数集合的中参数的名称,值,数据类型和是否为空组成SQL语句
*/
bool Create(const char* tableName, const vector<HisDBParamer>& paramers);
/**
* @brief 执行SQL语句,返回一个结果集合
* @param[in] tableName 数据库表名称
* @param[in] paramers 参数集合
* @retval true:成功,false;失败
* @note 自动根据表名、参数集合的中参数的名称,值,数据类型和是否为空组成SQL语句
*/
bool Delete(const char* tableName, const vector<HisDBParamer>& paramers);
public:
/**
* @brief 开启事物
* @retval true:成功,false;失败
*/
bool BeginTransaction(void);
/**
* @brief 提交事物
* @retval true:成功,false;失败
*/
bool CommitTransaction(void);
/**
* @brief 事物回滚
* @retval true:成功,false;失败
*/
bool RollbackTransaction(void);
public:
/**
* @brief 释放查询集合资源
* @param[in] table 查询的集合资源
* @retval true:成功,false;失败
*/
bool ReleaseHisDBTable(HisDBTable* table);
private:
/**
* @brief 数据库操作实现指针
*/
HisDBImpl* m_Impl; /**< 数据库操作实现指针 */
};
}
4 相关结构体定义
在接口定义中,使用到了很多自定义的结构体,这些结构体主要有三类:
- HisDBParamer: SQ语句参数,用户提供SQL语句时,根据需要提供参数,该库会自动根据SQL语句和参数生成完整的SQL语句。例如:用户提供SQL语句“Select * FROM Table1 Where ID=1 AND ?”,提供一个类型为string,field为name,值为test的参数,则库会自动生成如下语句:“Select * FROM Table1 Where ID=1 AND name='test'”。
- HisDBValue:存储查询结果中的一个值的结构体,属性包括该值是多少,类型是什么,field是什么等。
- HisDBTable: 存储查询结果的数组,数组中的每个元素是一个map,map的键是field,值是该行,field列的数据对象(HisDBValue),HisDBTable暂时使用typedef定义,以后可以考虑使用类定义。
此外还有一个异常结构体HisDBException,指明异常的位置,描述,错误编号等信息。还为HisDBException提供一个宏HisDBHelperOnError,修改宏可以决定是否使用异常,如果不使用异常,则返回false。
除结构体外,还有数据库类型枚举HisDBType和数据类型HisDBDataType。
5 相关结构体代码
#pragma once
#include "../Common//HisExport.h"
#include <string>
#include <vector>
#include <map>
using namespace std;
namespace His
{
/** @brief 数据库类型 */
typedef enum _HisDBType
{
HisDBType_Invail, /**< 无效类型 */
HisDBType_MySQL, /**< MySQL */
}HisDBType;
/** @brief 数据类型 */
typedef enum _HisDBDataType
{
HisDBDataType_Invail, /**< 无效类型 */
HisDBDataType_Short, /**< 短整数 */
//HisDBDataType_Int,
HisDBDataType_Long, /**< 长整数 */
HisDBDataType_LongLong, /**< 64位整数 */
//HisDBDataType_FLOAT,
HisDBDataType_DOUBLE, /**< 浮点数 */
//HisDBDataType_DECIMAL,
HisDBDataType_String, /**< 字符串 */
HisDBDataType_Date, /**< 日期 */
HisDBDataType_Time, /**< 时间 */
HisDBDataType_NULL, /**< 空值 */
}HisDBDataType;
typedef struct _HisDBValue
{
string m_Field;
string m_Value;
HisDBDataType m_DataType;
bool m_IsNull;
}HisDBValue;
typedef struct _HisDBParamer
{
string m_Name;
string m_Field;
string m_Value;
HisDBDataType m_DataType;
bool m_IsNull;
bool m_IsEqual;
}HisDBParamer;
#ifndef HisDBTable
typedef vector<map<string,HisDBValue>> HisDBTable;
#endif
typedef struct _HisDBException
{
string m_sql;
string m_descript;
string m_position;
long m_errorId;
HisDBType m_dbTyp;
}HisDBException;
}
//class HISCOMM_EXPORT HisDBTable
//{
//public:
// HisDBVector m_Vector;
//};
#define HisDBHelperOnError(ps, script,sql, id) \
His::HisDBException exception;\
exception.m_position = ps;\
exception.m_descript = script;\
exception.m_sql = sql;\
exception.m_errorId = id;\
throw exception;\
//return false;注:HisDBParamer的m_Name属性是后加的,主要考虑一次操作有两个或多个field相同或field为t.column的情况。
6 接下来:
接下来的文章会描述临界区的实现,数据库访问代码的实现。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?