这个class的设计是这样的,初始化的时候并不建立连接,仅仅简单地初始化成员变量(IP地址,User,password等),而是单独提供一个Connect函数来建立连接,连接的时候把mysql的编码设置为gb2312,关闭连接也有一个Close函数,析构的时候会调用Close.
Dump函数是用来debug用的,将m_pMysql指针指向的值打印出来。
MysqlObj并不使用QueryResult作为它的成员,只有在ExecuteSql的时候才简单的使用QueryResult的引用来接收查询结果。
如果是写SQL的话,也就是INSERT INTO,UPDATE INTO,DELETE 的话,由于会有受影响行数和插入id,所以需要使用成员变量m_iAffectedRows, m_iInsertId;来接收。
#ifndef _MYSQL_OBJ_H
#define _MYSQL_OBJ_H
#include <mysql/mysql.h>
#include "QueryResult.h"
#include "debug.h"
// 设置一个标志,函数参数列表当中带有OUT的就是输出引用,带有IN的就是输入参数
#define OUT
#define IN
class MysqlObj
{
public:
MysqlObj(string HostIP, string pUser, string pPassword, string pDBname, unsigned iPort);
virtual ~MysqlObj();
// Dump指的是把m_pMysql的指针指向的值打印出来
void Dump() const;
string ErrorMessage();
// 根据成员变量来建立MYSQL连接
bool Connect();
bool Reconnect();
void Close();
int SelectDB(const char* pDatabase);
int ExecuteSql(IN const char* pSql, OUT QueryResult& vecResult);
//执行SQL受到影响的行数
unsigned long long AffectedRows() const;
unsigned long long InsertId() const;
//返回MYSQL的指针
MYSQL* get() const;
//测试mysql服务器是否存活
bool Ping() const;
private:
// MYSQL代表了一条TCP连接
MYSQL* m_pMysql;
// 连接必备的参数:IP地址,用户,密码,数据库名称,端口号
string m_strHost;
string m_strUser;
string m_strPassword;
string m_strDBname;
unsigned m_iPort;
//错误信息
string m_strErrorMessage;
//
unsigned long long m_iAffectedRows;
unsigned long long m_iInsertId;
};
#endif /* MYSQL_OBJ_H */
================================================
2015年10月18号修改
为了使用shared_ptr来操作指针,增加了代码:
虽然我的ubuntu用的是gcc 4.8.4 但是考虑到centos的gcc版本可能不支持C++11的shared_ptr,所以直接使用boost::shared_ptr
typedef boost::shared_ptr<MysqlObj>MysqlObjPtr;
#include "../include/mysql_obj.h"
#include <assert.h>
#include <cstring>
MysqlObj::MysqlObj(string host, string user, string password, string dbname, unsigned port)
: m_strHost(host), m_strUser(user), m_strPassword(password), m_strDBname(dbname), m_iPort(port)
{
m_pMysql = NULL;
}
MysqlObj::~MysqlObj()
{
Close();
}
void MysqlObj::Dump() const
{
printf("m_pMysql=%p", m_pMysql);
}
string MysqlObj::ErrorMessage()
{
m_strErrorMessage = "";
if ( m_pMysql )
{
string pMessage = mysql_error(m_pMysql);
m_strErrorMessage = pMessage;
}
return m_strErrorMessage;
}
bool MysqlObj::Connect()
{
m_pMysql = mysql_init(NULL);
if ( NULL == m_pMysql )
{
return false;
}
char cValue = 1;
if ( 0 != mysql_options(m_pMysql, MYSQL_OPT_RECONNECT, (char *)&cValue) )
{
ErrorMessage();
Close();
return false;
}
if ( NULL == mysql_real_connect(m_pMysql, m_strHost.c_str(), m_strUser.c_str(), m_strPassword.c_str(), m_strDBname.c_str(), m_iPort, NULL, 0) )
{
ErrorMessage();
Close();
return false;
}
mysql_set_character_set(m_pMysql, "gb2312");
return true;
}
bool MysqlObj::Reconnect()
{
Close();
m_pMysql = mysql_init(NULL);
if ( NULL == m_pMysql )
{
return false;
}
if ( NULL == mysql_real_connect(m_pMysql,
m_strHost.size()?m_strHost.c_str():NULL,
m_strUser.size()?m_strUser.c_str():NULL,
m_strPassword.size()?m_strPassword.c_str():NULL,
m_strDBname.size()?m_strDBname.c_str():NULL,
m_iPort, NULL, CLIENT_MULTI_STATEMENTS) )
{
ErrorMessage();
Close();
return false;
}
return true;
}
void MysqlObj::Close()
{
if ( m_pMysql )
{
mysql_close(m_pMysql);
m_pMysql = NULL;
}
}
int MysqlObj::SelectDB(const char *pDatabase)
{
assert(m_pMysql);
int iRet = mysql_select_db(m_pMysql, pDatabase);
if (0 != iRet)
{
ErrorMessage();
}
return iRet;
}
int MysqlObj::ExecuteSql(IN const char *pSql, OUT QueryResult& vecResult)
{
assert(m_pMysql);
unsigned int iSqlSize = (unsigned int)strlen(pSql);
if ( 0 != mysql_real_query(m_pMysql, pSql, iSqlSize) )
{
ErrorMessage();
return -1;
}
unsigned iFieldCount = 0;
unsigned iRowCount = 0;
if ( 0 == (iFieldCount = mysql_field_count(m_pMysql)) )
{
// 当前结果集无数据,说明不是SELECT的Sql
m_iAffectedRows = mysql_affected_rows(m_pMysql);
m_iInsertId = mysql_insert_id(m_pMysql);
}
else
{
// Select的结果集
MYSQL_RES *pRes = mysql_store_result(m_pMysql);
if ( NULL == pRes )
{
ErrorMessage();
return -1;
}
// 获取行数
iRowCount = mysql_num_rows(pRes);
m_iAffectedRows = iRowCount;
// 当前为Select,修正insert_id为0
m_iInsertId = 0;
MYSQL_ROW pRow = NULL;
for ( unsigned i = 0;i < iRowCount;i++ )
{
pRow = mysql_fetch_row(pRes);
if ( !pRow )
{
ErrorMessage();
mysql_free_result(pRes);
return -1;
}
unsigned long *pLens = mysql_fetch_lengths(pRes);
if ( NULL == pLens )
{
ErrorMessage();
mysql_free_result(pRes);
return -1;
}
//构造一行
vector<string> vecRow;
for ( unsigned j = 0;j < iFieldCount;j++ )
{
vecRow.push_back(string(pRow[j], pLens[j]));
}
vecResult.addRow(vecRow);
}
// 释放当前结果集
mysql_free_result(pRes);
}
// XXX:只保留第一个结果集,后续的忽略
while(!mysql_next_result(m_pMysql))
{
if (0 == mysql_field_count(m_pMysql))
{
continue;
}
MYSQL_RES *pRes = mysql_store_result(m_pMysql);
if ( NULL == pRes )
{
ErrorMessage();
return -1;
}
// 释放当前结果集
mysql_free_result(pRes);
}
return 0;
}
unsigned long long MysqlObj::AffectedRows() const
{
return m_iAffectedRows;
}
unsigned long long MysqlObj::InsertId() const
{
return m_iInsertId;
}
MYSQL* MysqlObj::get() const
{
return m_pMysql;
}
bool MysqlObj::Ping() const
{
if(m_pMysql != NULL && !mysql_ping(m_pMysql))
return true;
else
return false;
}