本文共 5841 字,大约阅读时间需要 19 分钟。
一、头文件【存为 encapsulation_mysql.h】
#ifndef __ENCAPSULATION_MYSQL_H__ #define __ENCAPSULATION_MYSQL_H__
#include <iostream> #include <cassert> #include <set> #include <sys/shm.h> #include <string> #include <vector> #include <stdio.h> #include <string> #include <vector> #include <map> #include <time.h> #include <stdlib.h> #include <memory> #include <iconv.h> #include <dlfcn.h>
#include "mysql.h"
using namespace std; #define ERRMSG1(fmt,...) ; sprintf(m_szErrMsg, fmt, __VA_ARGS__); #define ERRMSG2(fmt,args...) ; sprintf(m_szErrMsg, "[%s 第 %d 行 ]; "fmt"\r\n" , __FILE__, __LINE__, ##args); namespace EncapMysql {
class CEncapMysql { typedef map<string, int> MapFieldNameIndex; public: CEncapMysql(); ~CEncapMysql();
public: int Connect(const char* szDbIp, const char* szUser, const char* szPassword);
void CloseConnect();
int SelectQuery(const char* szSQL);
int ModifyQuery(const char* szSQL);
const char* GetErrMsg();
char** FetchRow();
char* GetField(const char* szFieldName);
连接池那个类需要用到这3个函数。 2011-01-20 public: void SetUsed(); void SetIdle(); bool IsIdle(); //返回 true 标识 Idle private: bool m_bUseIdle; // true: use; false:idle private: bool IsConnected(); void SetConnected(bool bTrueFalse);
char* GetField(unsigned int iFieldIndex);
void FreePreResult();
int ReConnect();
void SaveParam(const char* szDbIp, const char* szUser, const char* szPassword);
public: bool m_bConnected;//数据库连接了吗? true--已经连接; false--还没有连接 char m_szErrMsg[1024]; //函数出错后, 错误信息放在此处
int m_iFields;//字段个数 MapFieldNameIndex m_mapFieldNameIndex;//是一个map, key是字段名, value是字段索引
public: MYSQL m_connection;//连接 MYSQL_RES* m_result;//结果集指针 MYSQL_ROW m_row;//一行, typedef char **MYSQL_ROW;
private: string m_sDbIp;//数据库服务器IP string m_sUser;//用户名 string m_sPassword;//口令
};
}//end of namespace EncapMysql
#endif
二、源码【存为 encapsulation_mysql.cpp】
#include <stdio.h> #include <string> #include <iostream> #include <fstream> #include <vector> #include <cassert> #include <set> #include <map> #include <stdio.h> #include <dirent.h> #include <sys/types.h> #include "encapsulation_mysql.h"
using namespace std; using namespace EncapMysql;
CEncapMysql::CEncapMysql() { SetConnected(false);
//把结果集置为空 m_result = NULL;
//初始化连接 mysql_init(&m_connection);
}
CEncapMysql::~CEncapMysql() { //释放上一次的结果集 FreePreResult();
//关闭数据库连接 CloseConnect(); }
int CEncapMysql::Connect(const char* szDbIp, const char* szUser, const char* szPassword) { SaveParam(szDbIp, szUser, szPassword);
//先判断是否已经连接了, 防止重复连接 if(IsConnected()) return 0;
//连接数据库 if (mysql_real_connect(&m_connection, szDbIp, szUser, szPassword, NULL, 0, NULL, 0) == NULL) { ERRMSG2 ("%s", mysql_error(&m_connection)); return -1; }
printf("[mysql] conn to %s [user:%s] succ!\r\n", szDbIp, szUser); //设置连接标志为 true SetConnected(true);
return 0; }
void CEncapMysql::CloseConnect() { //不论m_connection曾经是否连接过, 这样关闭都不会有问题 mysql_close(&m_connection); SetConnected(false); } int CEncapMysql::SelectQuery(const char* szSQL) { //如果查询串是空指针,则返回 if(szSQL == NULL) { ERRMSG2 ("%s", "szSQL==NULL"); return -1; } //如果还没有连接,则返回 if(!IsConnected()) { ERRMSG2 ("%s", "还没有建立连接"); return -2; }
try //这些语句与连接有关,出异常时就重连 { //查询 if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0 ) { ERRMSG2 ("%s", mysql_error(&m_connection)); printf("%s", mysql_error(&m_connection)); printf("ReConnect() is called, select111 !!!***\r\n"); int nRet = ReConnect(); if(nRet != 0) return -3; // if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0 ) return -33; // }
//释放上一次的结果集 FreePreResult();
//取结果集 m_result = mysql_store_result (&m_connection);
if (m_result == NULL) { ERRMSG2 ("%s", mysql_error(&m_connection)); return -4; } } catch(...) { printf("ReConnect() is called, select !!!***\r\n"); ReConnect(); return -5; }
//取字段的个数 m_iFields = mysql_num_fields (m_result); m_mapFieldNameIndex.clear();
//取各个字段的属性信息 MYSQL_FIELD *fields; fields = mysql_fetch_fields(m_result);
//把字段名字和索引保存到一个map中 for(unsigned int i = 0; i < m_iFields; i++) { m_mapFieldNameIndex[fields[i].name] = i; }
return 0; }
int CEncapMysql::ModifyQuery(const char* szSQL) { //如果查询串是空指针,则返回 if(szSQL == NULL) { ERRMSG2 ("%s", "szSQL==NULL"); return -1; }
//如果还没有连接,则返回 if(!IsConnected()) { ERRMSG2 ("%s", "还没有建立连接"); return -2; }
try//这些语句与连接有关,出异常时就重连 { //查询, 实际上开始真正地修改数据库 if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0 ) { ERRMSG2 ("%s", mysql_error(&m_connection)); return -3; } } catch(...) { printf("ReConnect() is called ,modify!!!***\r\n"); ReConnect(); return -5; } return 0; }
char** CEncapMysql::FetchRow() { //如果结果集为空,则直接返回空; 调用FetchRow之前, 必须先调用 SelectQuery(...) if (m_result == NULL) return NULL; //从结果集中取出一行 m_row = mysql_fetch_row (m_result);
return m_row; }
char* CEncapMysql::GetField(const char* szFieldName) { return GetField(m_mapFieldNameIndex[szFieldName]); }
char* CEncapMysql::GetField(unsigned int iFieldIndex) { //防止索引超出范围 if(iFieldIndex >= m_iFields) return NULL; return m_row[iFieldIndex]; }
void CEncapMysql::FreePreResult() { if(m_result != NULL) { mysql_free_result (m_result); m_result = NULL; }
}
const char* CEncapMysql::GetErrMsg() { return m_szErrMsg; }
bool CEncapMysql::IsConnected() { return m_bConnected; }
void CEncapMysql::SetConnected(bool bTrueFalse) { m_bConnected = bTrueFalse; }
void CEncapMysql::SaveParam(const char* szDbIp, const char* szUser, const char* szPassword) { m_sDbIp = szDbIp;//数据库服务器IP m_sUser = szUser;//用户名 m_sPassword = szPassword;//口令 } int CEncapMysql::ReConnect() { CloseConnect(); //连接数据库 if (mysql_real_connect(&m_connection, m_sDbIp.c_str(), m_sUser.c_str(), m_sPassword.c_str(), NULL, 0, NULL, 0) == NULL) { ERRMSG2 ("%s", mysql_error(&m_connection)); return -1; }
//设置连接标志为 true SetConnected(true); return 0; }
/ 连接池那个类需要用到这3个函数。 void CEncapMysql::SetUsed() { m_bUseIdle = true; }
void CEncapMysql::SetIdle() { m_bUseIdle = false; }
//如果空闲,返回true bool CEncapMysql::IsIdle() { return !m_bUseIdle; } 转载地址:http://lruvi.baihongyu.com/