整理了一下之前在公司写的MySQL封装类,分享一下
TableStruct.h定义了一个结构体,该结构体用来保存结果集的内容,更加人性化的展现出来
#pragma once #include <tchar.h> //函数输入输出参数标识 #define DB_OUT //函数输出参数 #define DB_IN //函数输入参数 //函数返回值 enum { MYSQL_DB_SUCCES, //数据库操作成功 MYSQL_DB_FAIL, //数据库操作失败 MYSQL_DB_NULL //数据库结果集为空 }; //数据库表基类 class CTableBase { protected: TCHAR m_wcVersion[8];//数据库版本号 public: CTableBase() { ZeroMemory(this, sizeof(CTableBase)); } virtual ~CTableBase() { ZeroMemory(this, sizeof(CTableBase)); } }; //数据库机器信息表 class CMachineInfo : public CTableBase { public: TCHAR m_nID[16]; //唯一标识 TCHAR m_wcNumber[32]; //机器标号 TCHAR m_wcSIM[8]; //SIM卡号 TCHAR m_wcSIMDate[10]; //SIM卡安装日期 TCHAR m_wcOrderNO[16]; //出货单号 TCHAR m_wcMAC[64]; //Mac地址 TCHAR m_wcIP[32]; //IP地址 TCHAR m_wcDate[10]; //出厂日期 TCHAR m_wcInstallDate[10]; //装机日期 TCHAR m_wcInstallMan[8]; //SIM卡装机人员 TCHAR m_wcState[2]; //机器状态(0:可用1:锁机) TCHAR m_wcProvince[16]; //省份 TCHAR m_wcCity[16]; //市 TCHAR m_wcAddress[128]; //地址信息 TCHAR m_wcLongitude[16]; //经度 TCHAR m_wcLatitude[16]; //纬度 TCHAR m_wcAddtion[2]; //是否添加成功(0:失败1:成功) TCHAR m_wcAgent[32]; //代理商 TCHAR m_wcClient[32]; //客户医院 TCHAR m_wcPrinter[8]; //附带打印机数量 TCHAR m_wcFunction[8]; //机器功能 TCHAR m_wcProbeType[8]; //探头型号 TCHAR m_wcLinkMan[8]; //联系人 TCHAR m_wcTelephone[32]; //联系电话 TCHAR m_wcRemark[64]; //备注 TCHAR m_wcUpdateTime[20];//更新时间 public: CMachineInfo() { ZeroMemory(this, sizeof(CMachineInfo)); } ~CMachineInfo() { ZeroMemory(this, sizeof(CMachineInfo)); } };
接下来是对MySQL结果集赋值到该结构体的封装
#pragma once #include "TableStruct.h" class CTableBaseOper { public: virtual HRESULT UpdateRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql) = 0; virtual HRESULT InsertRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql) = 0; virtual HRESULT DeleteRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql) = 0; virtual HRESULT SelectRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql, DB_IN bool bSelect=true) = 0; virtual HRESULT GetRes(DB_OUT MYSQL_RES *sRes) = 0; virtual HRESULT GetRowValue(DB_OUT CTableBase *pTable) = 0; virtual HRESULT GetRowCount(DB_OUT int *pRow) = 0; virtual HRESULT GetFieldCount(DB_OUT int *pCol) = 0; virtual HRESULT FreeRes() = 0; public: CTableBaseOper() { } ~CTableBaseOper() { } };这是纯虚基类定义标准
#pragma once #include "TableBaseOper.h" class CTableMachineInfoOper : public CTableBaseOper { public: CTableMachineInfoOper(); ~CTableMachineInfoOper(); /************************************************** *描述 : UpdateRecord *参数 : pHCon 当前连接数据库句柄 pSql 指定sql语句 *返回值: HRESULT 成功返回MYSQL_DB_SUCCES,失败返回MYSQL_DB_FAIL *说明 : 函数用于修改数据库,内部实际上调用SelectRecord执行sql语句 **************************************************/ HRESULT UpdateRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql); /************************************************** *描述 : InsertRecord *参数 : pHCon 当前连接数据库句柄 pSql 指定sql语句 *返回值: HRESULT 成功返回MYSQL_DB_SUCCES,失败返回MYSQL_DB_FAIL *说明 : 函数用于加入数据库,内部实际上调用SelectRecord执行sql语句 **************************************************/ HRESULT InsertRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql); /************************************************** *描述 : DeleteRecord *参数 : pHCon 当前连接数据库句柄 pSql 指定sql语句 *返回值: HRESULT 成功返回MYSQL_DB_SUCCES,失败返回MYSQL_DB_FAIL *说明 : 函数用于删除数据库,内部实际上调用SelectRecord执行sql语句 **************************************************/ HRESULT DeleteRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql); /************************************************** *描述 : SelectRecord *参数 : pHCon 当前连接数据库句柄 pSql 指定sql语句 bSelect 当bSelect位true时为查询,默认为查询功能 *返回值: HRESULT 成功返回MYSQL_DB_SUCCES,失败返回MYSQL_DB_FAIL *说明 : 函数用于查询数据库 **************************************************/ HRESULT SelectRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql, DB_IN bool bSelect=true); /************************************************** *描述 : GetRes *参数 : sRes 获取数据库结果集 *返回值: HRESULT 成功返回MYSQL_DB_SUCCES,失败返回MYSQL_DB_FAIL *说明 : 函数用于获取数据库结果集 **************************************************/ HRESULT GetRes(DB_OUT MYSQL_RES *sRes); /************************************************** *描述 : GetRowValue *参数 : pTable 当前表对象指针 *返回值: HRESULT 成功返回MYSQL_DB_SUCCES,失败返回MYSQL_DB_FAIL *说明 : 函数用于获取数据库指定行结果集记录值 **************************************************/ HRESULT GetRowValue(DB_OUT CTableBase *pTable); /************************************************** *描述 : GetRowCount *参数 : pRow 保存当前查询结果集行数 *返回值: HRESULT MYSQL_DB_SUCCES 成功,其它值为失败 *说明 : 函数用于获取当前查询结果集行数 **************************************************/ HRESULT GetRowCount(DB_OUT int *pRow); /************************************************** *描述 : GetFieldCount *参数 : pCol 保存当前查询结果集列数 *返回值: HRESULT MYSQL_DB_SUCCES 成功,其它值为失败 *说明 : 函数用于获取当前查询结果集列数 **************************************************/ HRESULT GetFieldCount(DB_OUT int *pCol); /************************************************** *描述 : FreeRes *参数 : *返回值: HRESULT MYSQL_DB_SUCCES 成功,其它值为失败 *说明 : 函数用于释放当前表操作基类指针指向的表的结果集 **************************************************/ HRESULT FreeRes(); private: MYSQL_RES *m_pResult; //查询结果集 int m_nRow; //查询结果行数 int m_nColumn; //查询结果字段数 };然后是定义
#include "stdafx.h" #include "TableMachineInfoOper.h" #include "DBFunction.h" CTableMachineInfoOper::CTableMachineInfoOper() { m_pResult = NULL; m_nRow = 0; m_nColumn = 0; } CTableMachineInfoOper::~CTableMachineInfoOper() { FreeRes(); } HRESULT CTableMachineInfoOper::UpdateRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql) { return SelectRecord(pHCon, pSql, false); } HRESULT CTableMachineInfoOper::InsertRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql) { return SelectRecord(pHCon, pSql, false); } HRESULT CTableMachineInfoOper::DeleteRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql) { return SelectRecord(pHCon, pSql, false); } HRESULT CTableMachineInfoOper::SelectRecord(DB_IN MYSQL *pHCon, DB_IN const TCHAR *pSql, DB_IN bool bSelect) { HRESULT hRet = MYSQL_DB_SUCCES; char *pStrSql = DBUnicodeToUTF8(pSql); int nLength = strlen(pStrSql); int nStatus = mysql_real_query(pHCon, pStrSql, nLength); free(pStrSql); pStrSql = NULL; if (0 != nStatus) { hRet = MYSQL_DB_FAIL; } else { if (bSelect) { m_pResult = mysql_store_result(pHCon); m_nRow = mysql_num_rows(m_pResult); m_nColumn = mysql_num_fields(m_pResult); } } return hRet; } HRESULT CTableMachineInfoOper::GetRes(DB_OUT MYSQL_RES *sRes) { HRESULT hRet = MYSQL_DB_FAIL; if (NULL != m_pResult) { *sRes = *m_pResult; hRet = MYSQL_DB_SUCCES; } return hRet; } HRESULT CTableMachineInfoOper::GetRowValue(DB_IN CTableBase *pTable) { HRESULT hRet = MYSQL_DB_SUCCES; MYSQL_ROW row; if (NULL != m_pResult) { row = mysql_fetch_row(m_pResult); if (NULL != row) { CMachineInfo *pMachine = (CMachineInfo*)pTable; TCHAR *pTemp = NULL; pTemp = DBUTF8ToUnicode(row[0]); if (pTemp) { _tcsncpy_s(pMachine->m_nID, _countof(pMachine->m_nID), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[1]); if (pTemp) { _tcsncpy_s(pMachine->m_wcNumber, _countof(pMachine->m_wcNumber), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[2]); if (pTemp) { _tcsncpy_s(pMachine->m_wcSIM, _countof(pMachine->m_wcSIM), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[3]); if (pTemp) { _tcsncpy_s(pMachine->m_wcSIMDate, _countof(pMachine->m_wcSIMDate), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[4]); if (pTemp) { _tcsncpy_s(pMachine->m_wcOrderNO, _countof(pMachine->m_wcOrderNO), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[5]); if (pTemp) { _tcsncpy_s(pMachine->m_wcMAC, _countof(pMachine->m_wcMAC), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[6]); if (pTemp) { _tcsncpy_s(pMachine->m_wcIP, _countof(pMachine->m_wcIP), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[7]); if (pTemp) { _tcsncpy_s(pMachine->m_wcDate, _countof(pMachine->m_wcDate), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[8]); if (pTemp) { _tcsncpy_s(pMachine->m_wcInstallDate, _countof(pMachine->m_wcInstallDate), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[9]); if (pTemp) { _tcsncpy_s(pMachine->m_wcInstallMan, _countof(pMachine->m_wcInstallMan), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[10]); if (pTemp) { _tcsncpy_s(pMachine->m_wcState, _countof(pMachine->m_wcState), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[11]); if (pTemp) { _tcsncpy_s(pMachine->m_wcProvince, _countof(pMachine->m_wcProvince), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[12]); if (pTemp) { _tcsncpy_s(pMachine->m_wcCity, _countof(pMachine->m_wcCity), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[13]); if (pTemp) { _tcsncpy_s(pMachine->m_wcAddress, _countof(pMachine->m_wcAddress), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[14]); if (pTemp) { _tcsncpy_s(pMachine->m_wcLongitude, _countof(pMachine->m_wcLongitude), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; }pTemp = DBUTF8ToUnicode(row[15]); if (pTemp) { _tcsncpy_s(pMachine->m_wcLatitude, _countof(pMachine->m_wcLatitude), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[16]); if (pTemp) { _tcsncpy_s(pMachine->m_wcAddtion, _countof(pMachine->m_wcAddtion), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[17]); if (pTemp) { _tcsncpy_s(pMachine->m_wcAgent, _countof(pMachine->m_wcAgent), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[18]); if (pTemp) { _tcsncpy_s(pMachine->m_wcClient, _countof(pMachine->m_wcClient), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[19]); if (pTemp) { _tcsncpy_s(pMachine->m_wcPrinter, _countof(pMachine->m_wcPrinter), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[20]); if (pTemp) { _tcsncpy_s(pMachine->m_wcFunction, _countof(pMachine->m_wcFunction), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[21]); if (pTemp) { _tcsncpy_s(pMachine->m_wcProbeType, _countof(pMachine->m_wcProbeType), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[22]); if (pTemp) { _tcsncpy_s(pMachine->m_wcLinkMan, _countof(pMachine->m_wcLinkMan), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[23]); if (pTemp) { _tcsncpy_s(pMachine->m_wcTelephone, _countof(pMachine->m_wcTelephone), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[24]); if (pTemp) { _tcsncpy_s(pMachine->m_wcRemark, _countof(pMachine->m_wcRemark), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } pTemp = DBUTF8ToUnicode(row[25]); if (pTemp) { _tcsncpy_s(pMachine->m_wcUpdateTime, _countof(pMachine->m_wcUpdateTime), pTemp, _TRUNCATE); free(pTemp); pTemp = NULL; } } else { hRet = MYSQL_DB_FAIL; } } else { hRet = MYSQL_DB_FAIL; } return hRet; } HRESULT CTableMachineInfoOper::GetRowCount(DB_OUT int *pRow) { HRESULT hRet = MYSQL_DB_FAIL; if (NULL != m_pResult) { *pRow = m_nRow; hRet = MYSQL_DB_SUCCES; } return hRet; } HRESULT CTableMachineInfoOper::GetFieldCount(DB_OUT int *pCol) { HRESULT hRet = MYSQL_DB_FAIL; if (NULL != m_pResult) { *pCol = m_nColumn; hRet = MYSQL_DB_SUCCES; } return hRet; } HRESULT CTableMachineInfoOper::FreeRes() { if (NULL != m_pResult) { mysql_free_result(m_pResult); m_pResult = NULL; m_nRow = 0; m_nColumn = 0; } return MYSQL_DB_SUCCES; }其中DBUTF8ToUnicode是因为数据库我使用了utf-8编码,查询出来的结果集需要通过函数转码到unicode,也就是wchar,这个函数是自定义写的。接下来是对SQL语句的封装类
#pragma once #include "TableBaseOper.h" #include "TableMachineInfoOper.h" #include <windows.h> #include <WinSock2.h> #include <iostream> using namespace std; #include "mysql.h" #pragma comment(lib, "libmysql.lib") class CETCDDBOper { public: CETCDDBOper(); ~CETCDDBOper(); public: /************************************************** *描述 : Connect *参数 : host 指定服务器地址 user 指定数据库用户名 passWd 指定数据库密码 db 指定数据库名 port 指定端口号 *返回值: HRESULT MYSQL_DB_SUCCES 成功,其它值为失败 *说明 : 函数用于根据提供的参数连接指定的数据库 **************************************************/ HRESULT Connect(DB_IN const char *pHost, DB_IN const char *pUser, DB_IN const char *pPassWd, DB_IN const char *pDb, DB_IN unsigned int uPort); /************************************************** *描述 : Close *参数 : *返回值: HRESULT MYSQL_DB_SUCCES 成功,其它值为失败 *说明 : 函数用于关闭数据库连接,关闭数据库连接实例赋值NULL **************************************************/ HRESULT Close(); /************************************************** *描述 : FreeRes *参数 : *返回值: HRESULT MYSQL_DB_SUCCES 成功,其它值为失败 *说明 : 函数用于释放当前表操作基类指针指向的表的结果集(在当前数据库操作类中保存了结果集,行值,列值并没有被清除掉) **************************************************/ HRESULT FreeRes(); /************************************************** *描述 : GetRowCount *参数 : pRow 保存当前查询结果集行数 *返回值: HRESULT MYSQL_DB_SUCCES 成功,其它值为失败 *说明 : 函数用于获取当前查询结果集行数(获取当前数据库操作类中保存的行值) **************************************************/ HRESULT GetRowCount(DB_OUT int *pRow); /************************************************** *描述 : GetFieldCount *参数 : pCol 保存当前查询结果集列数 *返回值: HRESULT MYSQL_DB_SUCCES 成功,其它值为失败 *说明 : 函数用于获取当前查询结果集列数(获取当前数据库操作类中保存的列值) **************************************************/ HRESULT GetFieldCount(DB_OUT int *pCol); /************************************************** *描述 : GetRowValue *参数 : pRes 保存结果集当前行的数据 *返回值: HRESULT MYSQL_DB_SUCCES 成功,MYSQL_DB_FAIL反复查询结束,MYSQL_DB_NULL结果集为空 *说明 : 函数用于反复使用往下读取结果集中的数据(逐行进行获取,加了临界区锁,最好在循环体中直接全部循环使用,避免另外的线程移动了结果集指针) **************************************************/ HRESULT GetRowValue(DB_OUT CTableBase *pTable); /************************************************** *描述 : SelectMachineInfoByAgent *参数 : pAgent 指定该行的代理商名称 *返回值: HRESULT MYSQL_DB_SUCCES 成功,其它值为失败 *说明 : 函数用于根据提供的代理商名称查找该代理商下的机器信息,之后再调用GetRowValue **************************************************/ HRESULT SelectMachineInfoByAgent(DB_IN const TCHAR *pAgent); private: MYSQL *m_mySql; //数据库连接句柄 CTableBaseOper *m_pBaseOper; //基类表操作指针 CTableMachineInfoOper m_cMachineInfoOper; //机器信息表操作对象 TCHAR m_wcMachineTabelName[64]; //保存当前操作机器信息表的表名 };然后是类的定义
#include "stdafx.h" #include "ETCDDBOper.h" #include "DBFunction.h" CETCDDBOper::CETCDDBOper() { m_mySql = NULL; m_mySql = mysql_init(NULL); m_pBaseOper = NULL; } CETCDDBOper::~CETCDDBOper() { m_pBaseOper = NULL; } HRESULT CETCDDBOper::Connect(DB_IN const char *pHost, DB_IN const char *pUser, DB_IN const char *pPassWd, DB_IN const char *pDb, DB_IN unsigned int uPort) { HRESULT hRet = MYSQL_DB_SUCCES; int nValue = 1; mysql_options(m_mySql, MYSQL_OPT_RECONNECT, (char *)&nValue);// 断线自动重连 mysql_options(m_mySql, MYSQL_SET_CHARSET_NAME, "utf8");//设置字符集 MYSQL *pStatus = mysql_real_connect(m_mySql, pHost, pUser, pPassWd, pDb, uPort, NULL, 0); //数据库连接失败返回空 if (NULL == pStatus) { hRet = MYSQL_DB_FAIL; } return hRet; } HRESULT CETCDDBOper::Close() { HRESULT hRet = MYSQL_DB_FAIL; //数据库连接状态下才关闭 if (NULL != m_mySql) { mysql_close(m_mySql); m_mySql = NULL; hRet = MYSQL_DB_SUCCES; } return hRet; } HRESULT CETCDDBOper::SelectMachineInfoByAgent(DB_IN const TCHAR *pAgent) { TCHAR wcSql[125] = {0}; _stprintf_s(wcSql, _countof(wcSql), _T("SELECT * FROM %s WHERE Agent = '%s'"), m_wcMachineTabelName, pAgent); HRESULT hRet = m_cMachineInfoOper.SelectRecord(m_mySql, wcSql); if (MYSQL_DB_SUCCES == hRet) { m_pBaseOper = &m_cMachineInfoOper; } return hRet; } HRESULT CETCDDBOper::FreeRes() { HRESULT hRet = MYSQL_DB_FAIL; if (NULL != m_pBaseOper) { hRet = m_pBaseOper->FreeRes(); m_pBaseOper = NULL; } return hRet; } HRESULT CETCDDBOper::GetRowCount(DB_OUT int *pRow) { HRESULT hRet = MYSQL_DB_FAIL; if (NULL != m_pBaseOper) { hRet = m_pBaseOper->GetRowCount(pRow); } return hRet; } HRESULT CETCDDBOper::GetFieldCount(DB_OUT int *pCol) { HRESULT hRet = MYSQL_DB_FAIL; if (NULL != m_pBaseOper) { hRet = m_pBaseOper->GetFieldCount(pCol); } return hRet; } HRESULT CETCDDBOper::GetRowValue(DB_OUT CTableBase *pTable) { HRESULT hRet = MYSQL_DB_FAIL; if (NULL != m_pBaseOper) { hRet = m_pBaseOper->GetRowValue(pTable); } return hRet; }