您的位置:首页 > 编程语言 > C语言/C++

MySQL C++接口封装

2014-09-12 08:47 405 查看
CppMysql.h

#ifndef _DATA_BASE_MYSQL_H_
#define _DATA_BASE_MYSQL_H_

#include "ResultSet.h"

namespace sql{

//#define USE_EMBEDDED_MYSQL

// 错误码
enum
{
MYSQL_SUCCESS = 0, // 成功
MYSQL_E_DBINIT = 1, // 数据库初始化失败
MYSQL_E_CONNECT = 2, // 数据库连接失败
MYSQL_E_QUERY = 3, // 执行查询语句失败
MYSQL_E_RESULT = 4, // 获取结果集出错
MYSQL_E_PARAM = 5, // 参数错误
MYSQL_E_MEMALLOC = 6, // 内存分配失败
};

/** @class CppMysql
* @brief 数据库类
*/
class CppMysql
{
public:
CppMysql(void);
~CppMysql(void);

// 连接数据库
int connect(const char* strHost,
unsigned short nPort,
const char* strUsername,
const char* strPassword,
const char* strDatabase);

// 连接是否关闭
bool isClosed();

// 设置结果集每次从数据库获取的行数
void setFetchSize(size_t nRows);

// 执行SQL语句
int execute(const char* strSql, unsigned long lLength = 0);

// 执行非查询SQL语句
int executeUpdate(const char* strSql, unsigned long lLength = 0);

// 获取更新的记录数
int getUpdateCount();

// 执行查询SQL语句
ResultSet* executeQuery(const char* strSql, unsigned long lLength = 0);

// 关闭句柄
void closeMysql();

// 设置字符集
void setCharSet(const char *strSet);

protected:
// 打印错误信息
void printSqlError();

private:
MYSQL* m_pMysql; // MySQL连接句柄
size_t m_nFetchRows; // 结果集每次从数据库获取的行数
my_ulonglong m_nAffectedRows; // 更新的记录数
};

} // end of "namespace sql'

#endif


CppMysql.cpp

#include <cassert>
#include "CppMysql.h"

#ifdef USE_EMBEDDED_MYSQL
#pragma comment(lib, "libmysqld.lib")
#else
#pragma comment(lib, "libmysql.lib")
#endif

using namespace sql;

CppMysql::CppMysql(void)
: m_pMysql(NULL)
, m_nFetchRows(1)
, m_nAffectedRows(0)
{
}

CppMysql::~CppMysql(void)
{
if (m_pMysql)
{
mysql_close(m_pMysql);
m_pMysql = NULL;
}

#ifdef USE_EMBEDDED_MYSQL
mysql_library_end();
#endif
}

/** @fn int CppMysql::connect(const char* strHost,
unsigned short nPort,
const char* strUsername,
const char* strPassword,
const char* strDatabase)
* @brief 连接数据库服务器
* @param strHost [in] - 主机地址
nPort [in] - 端口号
strUsername [in] - 用户名
strPassword [in] - 密码
strDatabase [in] - 数据库
* @return 错误码
*/
int CppMysql::connect(const char* strHost,
unsigned short nPort,
const char* strUsername,
const char* strPassword,
const char* strDatabase)
{
#ifdef USE_EMBEDDED_MYSQL
char* pServerOptions[] = {"this_program",
"--datadir=./data",
"--language=./data/english",
"--key_buffer_size=64M",
"--skip-innodb",
};

if (mysql_library_init(sizeof(pServerOptions) / sizeof(char*), pServerOptions, NULL))
{
m_pMysql = NULL;
return MYSQL_E_DBINIT;
}
#endif

if (!m_pMysql)
{
m_pMysql = mysql_init(NULL);
if (!m_pMysql)
{
return MYSQL_E_DBINIT;
}
}

#ifdef USE_EMBEDDED_MYSQL
mysql_options(m_pMysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
#endif

if (mysql_real_connect(m_pMysql, strHost, strUsername, strPassword, strDatabase, nPort, NULL, 0))
{
return MYSQL_SUCCESS;
}
else
{
printSqlError();
return MYSQL_E_CONNECT;
}
}

/** @fn bool CppMysql::isClosed()
* @brief 连接是否关闭
* @param
* @return true:连接关闭 false:连接正常
*/
bool CppMysql::isClosed()
{
if (!m_pMysql)
{
return true;
}

if (mysql_ping(m_pMysql) != MYSQL_SUCCESS)
{
printSqlError();
return true;
}
else
{
return false;
}
}

/** @fn void CppMysql::setFetchSize(size_t nRows)
* @brief 设置结果集每次从数据库获取的行数
* @param nRows [in] - 行数,0表示全部获取
* @return
*/
void CppMysql::setFetchSize(size_t nRows)
{
m_nFetchRows = nRows;
}

/** @fn void CppMysql::printSqlError()
* @brief 打印错误信息
* @param
* @return
*/
void CppMysql::printSqlError()
{
assert(m_pMysql != NULL);
printf("mysql error %d, %s", mysql_errno(m_pMysql), mysql_error(m_pMysql));
}

/** @fn int CppMysql::execute(const char* strSql, unsigned long lLength)
* @brief 执行SQL语句,如果有结果集,直接释放
* @param strSql [in] - SQL语句
* @param lLength [in] - SQL语句长度
* @return 错误码
*/
int CppMysql::execute(const char* strSql, unsigned long lLength)
{
int nRet = executeUpdate(strSql, lLength);

if (nRet == MYSQL_SUCCESS)
{
MYSQL_RES* pMysqlRes = mysql_store_result(m_pMysql);
if (pMysqlRes)
{
mysql_free_result(pMysqlRes);
}
}

return nRet;
}

/** @fn int CppMysql::executeUpdate(const char* strSql, unsigned long lLength)
* @brief 执行非查询SQL语句(不判断结果集,外部调用时注意)
* @param strSql [in] - SQL语句
* @param lLength [in] - SQL语句长度
* @return 错误码
*/
int CppMysql::executeUpdate(const char* strSql, unsigned long lLength)
{
if (!m_pMysql || !strSql)
{
return MYSQL_E_PARAM;
}
if (lLength == 0)
{
lLength = (unsigned long)strlen(strSql);
}

if (mysql_real_query(m_pMysql, strSql, lLength) == MYSQL_SUCCESS)
{
m_nAffectedRows = mysql_affected_rows(m_pMysql);
return MYSQL_SUCCESS;
}
else
{
printSqlError();
return MYSQL_E_QUERY;
}
}

/** @fn int CppMysql::getUpdateCount()
* @brief 获取更新的记录数
* @param
* @return 更新的记录数
*/
int CppMysql::getUpdateCount()
{
return (int)m_nAffectedRows;
}

/** @fn ResultSet* CppMysql::executeQuery(const char* strSql, unsigned long lLength)
* @brief 执行查询SQL语句
* @param strSql [in] - SQL语句
* @param lLength [in] - SQL语句长度
* @return 结果集
*/
ResultSet* CppMysql::executeQuery(const char* strSql, unsigned long lLength)
{
if (!m_pMysql || !strSql)
{
return NULL;
}
if (lLength == 0)
{
lLength = (unsigned long)strlen(strSql);
}

if (mysql_real_query(m_pMysql, strSql, lLength) != MYSQL_SUCCESS)
{
printSqlError();
return NULL;
}

MYSQL_RES* pMysqlRes = NULL;
if (m_nFetchRows == 0)
{
pMysqlRes = mysql_store_result(m_pMysql);
}
else
{
pMysqlRes = mysql_use_result(m_pMysql);
}

// 无结果集时,判断是否是内存分配错误
if (!pMysqlRes && mysql_errno(m_pMysql) != MYSQL_SUCCESS)
{
printSqlError();
return NULL;
}

try
{
ResultSet* pResultSet = new ResultSet;
pResultSet->m_pMysql = m_pMysql;
pResultSet->m_pMysqlRes = pMysqlRes;
return pResultSet;
}
catch (...)
{
mysql_free_result(pMysqlRes);
return NULL;
}
}

void CppMysql::closeMysql()
{
if (m_pMysql)
{
mysql_close(m_pMysql);
m_pMysql = NULL;
}
}

void CppMysql::setCharSet(const char *strSet)
{
mysql_set_character_set(m_pMysql, strSet);
}


ResultSet.h

4000
#ifndef RESULTSET_H
#define RESULTSET_H

#include <map>
#include <string>
#include <WinSock2.h>
#include "mysql/mysql.h"

namespace sql{

#if (defined _WIN32 || defined _WIN64)
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#endif

class CppMysql;

/** @class ResultSet
* @brief 结果集
*/
class ResultSet
{
friend class CppMysql;

public:
ResultSet();
~ResultSet();

// 下一条记录
bool next();

// 总记录数
size_t rowsCount() const;

// 获取int字段
int32_t getInt(unsigned int nColumnIndex);
int32_t getInt(std::string strColumnLabel);

// 获取uint字段
uint32_t getUInt(unsigned int nColumnIndex);
uint32_t getUInt(std::string strColumnLabel);

// 获取stirng字段
std::string getString(unsigned int nColumnIndex);
std::string getString(std::string strColumnLabel);

protected:
// 初始化列名映射
void initColumnNameMap();

private:
MYSQL* m_pMysql; // MySQL连接句柄
MYSQL_RES* m_pMysqlRes; // MySQL结果集
MYSQL_ROW m_pMysqlRow; // MySQL一行结果
std::map<std::string, int> m_mapColumnName; // 列名映射
};

} // end of "namespace sql'

#endif


ResultSet.cpp
#include "ResultSet.h"

#ifdef USE_EMBEDDED_MYSQL
#pragma comment(lib, "libmysqld.lib")
#else
#pragma comment(lib, "libmysql.lib")
#endif

using namespace sql;

ResultSet::ResultSet(void)
: m_pMysql(NULL)
, m_pMysqlRes(NULL)
{
}

ResultSet::~ResultSet(void)
{
if (m_pMysqlRes)
{
mysql_free_result(m_pMysqlRes);
}
}

/** @fn bool ResultSet::next()
* @brief 下一条数据
* @param
* @return true:切换到下一条数据 false:已经是最后一条数据
*/
bool ResultSet::next()
{
initColumnNameMap();

if (m_pMysqlRes)
{
m_pMysqlRow = mysql_fetch_row(m_pMysqlRes);
return (m_pMysqlRow != NULL);
}
else
{
return false;
}
}

/** @fn size_t ResultSet::rowsCount() const
* @brief 获取总结果数
* @param
* @return 总结果数
*/
size_t ResultSet::rowsCount() const
{
if (m_pMysqlRes)
{
return (size_t)m_pMysqlRes->row_count;
}
else
{
return 0;
}
}

/** @fn void ResultSet::initColumnNameMap()
* @brief 初始化列名映射
* @param
* @return
*/
void ResultSet::initColumnNameMap()
{
if (!m_mapColumnName.empty() || !m_pMysqlRes)
{
return;
}

MYSQL_FIELD* pMysqlField = NULL;

int nIndex = 0;
while (true)
{
pMysqlField = mysql_fetch_field(m_pMysqlRes);
if (pMysqlField)
{
std::string strName(pMysqlField->name);
for (size_t i = 0; i < strName.length(); ++i)
{
strName[i] = tolower(strName[i]);
}
m_mapColumnName[strName] = nIndex++;
}
else
{
break;
}
}
}

/** @fn int32_t ResultSet::getInt(unsigned int nColumnIndex)
* @brief 获取int字段
* @param nColumnIndex [in] - 列索引
* @return int字段
*/
int32_t ResultSet::getInt(unsigned int nColumnIndex)
{
if (m_pMysqlRow && m_pMysqlRow[nColumnIndex])
{
return atoi(m_pMysqlRow[nColumnIndex]);
}
else
{
return 0;
}
}

/** @fn int32_t ResultSet::getInt(std::string strColumnLabel)
* @brief 获取int字段
* @param strColumnLabel [in] - 列名
* @return int字段
*/
int32_t ResultSet::getInt(std::string strColumnLabel)
{
return getInt(m_mapColumnName[strColumnLabel]);
}

/** @fn int32_t ResultSet::getUInt(unsigned int nColumnIndex)
* @brief 获取uint字段
* @param nColumnIndex [in] - 列索引
* @return uint字段
*/
uint32_t ResultSet::getUInt(unsigned int nColumnIndex)
{
if (m_pMysqlRow && m_pMysqlRow[nColumnIndex])
{
return atoi(m_pMysqlRow[nColumnIndex]);
}
else
{
return 0;
}
}

/** @fn int32_t ResultSet::getUInt(std::string strColumnLabel)
* @brief 获取uint字段
* @param strColumnLabel [in] - 列名
* @return uint字段
*/
uint32_t ResultSet::getUInt(std::string strColumnLabel)
{
return getUInt(m_mapColumnName[strColumnLabel]);
}

/** @fn int32_t ResultSet::getString(unsigned int nColumnIndex)
* @brief 获取string字段
* @param nColumnIndex [in] - 列索引
* @return string字段
*/
std::string ResultSet::getString(unsigned int nColumnIndex)
{
if (m_pMysqlRow && m_pMysqlRow[nColumnIndex])
{
return m_pMysqlRow[nColumnIndex];
}
else
{
return "";
}
}

/** @fn int32_t ResultSet::getString(std::string strColumnLabel)
* @brief 获取string字段
* @param strColumnLabel [in] - 列名
* @return string字段
*/
std::string ResultSet::getString(std::string strColumnLabel)
{
return getString(m_mapColumnName[strColumnLabel]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ mysql 接口