清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
先看 @红薯 写的 Linux下MySQL C++连接操作这个是简单的MySQL操作封装,已编译通过
编译的时候
加上参数 $(mysql_config --cflags --libs) 或者 -L/usr/lib/mysql -lmysqlclient
看了这个就可以看MySQL连接池的实现。
代码来自:在LINUX下用C/C++写了个操作MYSQL的类,挺好用。
/* * encapsulation_mysql.h * * Created on: 2013-3-28 * Author: holy */ #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/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_H_ */
/* * encapsulation_mysql.cpp * * Created on: 2013-3-28 * Author: holy */ #include <stdio.h> #include <string> #include <string.h> #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; }
/* * main.cpp * * Created on: 2013-3-26 * Author: holy */ #include "encapsulation_mysql.h" using EncapMysql::CEncapMysql; int main(int argc, char *argv[]) { CEncapMysql *con; con = new CEncapMysql; con->Connect("127.0.0.1", "root", "123456"); con->SelectQuery("select * from holy.student"); while (char** r = con->FetchRow()) printf("%s\t%s\t%s\n", r[0], r[1], r[2]); return 0; }