├── .gitignore ├── README.md └── mysqlpool ├── MysqlPool ├── Makefile ├── main.cpp ├── include └── mysqlpool.h └── mysqlpool.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | cscope.* 2 | tags 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MysqlPool 2 | MySql数据库的连接池实现,多用户的数据库访问。能够很好的管理数据库的连接 3 | -------------------------------------------------------------------------------- /mysqlpool/MysqlPool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/primer9999/MysqlPool/HEAD/mysqlpool/MysqlPool -------------------------------------------------------------------------------- /mysqlpool/Makefile: -------------------------------------------------------------------------------- 1 | MYSQLPOOL_INCLUDE=./include 2 | 3 | INCLUDE=-I$(MYSQLPOOL_INCLUDE) 4 | 5 | BINARY=$(patsubst %.cpp,%.o,$(wildcard *.cpp)) 6 | FLAG=-g -Wall -std=c++11 $$(mysql_config --cflags --libs) 7 | TARGET=MysqlPool 8 | all:$(TARGET) 9 | 10 | $(TARGET):$(BINARY) 11 | g++ $(FLAG) $^ -o $@ 12 | 13 | %.o:%.cpp 14 | g++ $(FLAG) $< -o $@ -c $(INCLUDE) 15 | 16 | clean: 17 | rm -rf *.o 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /mysqlpool/main.cpp: -------------------------------------------------------------------------------- 1 | #include"include/mysqlpool.h" 2 | 3 | int main() { 4 | MysqlPool *mysql = MysqlPool::getMysqlPoolObject(); 5 | mysql->setParameter("localhost","root","root","mysqltest",0,NULL,0,2); 6 | std::map > m = mysql->executeSql("select * from test"); 7 | for (std::map >::iterator it = m.begin() ; it != m.end(); ++it) { 8 | std::cout << it->first << std::endl; 9 | const std::string field = it->first; 10 | for (size_t i = 0;i < m[field].size();i++) { 11 | std::cout << m[field][i] << std::endl; 12 | } 13 | } 14 | delete mysql; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /mysqlpool/include/mysqlpool.h: -------------------------------------------------------------------------------- 1 | #ifndef MYSQLPOOL_H 2 | #define MYSQLPOOL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | 16 | class MysqlPool { 17 | public: 18 | ~MysqlPool(); 19 | std::map > executeSql(const char* sql);//sql语句的执行函数 20 | static MysqlPool* getMysqlPoolObject(); //单列模式获取本类的对象 21 | void setParameter( const char* _mysqlhost, 22 | const char* _mysqluser, 23 | const char* _mysqlpwd, 24 | const char* _databasename, 25 | unsigned int _port = 0, 26 | const char* _socket = NULL, 27 | unsigned long _client_flag = 0, 28 | unsigned int MAX_CONNECT = 50 ); //设置数据库参数 29 | private: 30 | MysqlPool(); 31 | MYSQL* createOneConnect(); //创建一个新的连接对象 32 | MYSQL* getOneConnect(); //获取一个连接对象 33 | void close(MYSQL* conn); //关闭连接对象 34 | bool isEmpty(); //连接池队列池是否为空 35 | MYSQL* poolFront(); //连接池队列的队头 36 | unsigned int poolSize(); //获取连接池的大小 37 | void poolPop(); //弹出连接池队列的队头 38 | private: 39 | std::queue mysqlpool; //连接池队列 40 | const char* _mysqlhost; //mysql主机地址 41 | const char* _mysqluser; //mysql用户名 42 | const char* _mysqlpwd; //mysql密码 43 | const char* _databasename; //要使用的mysql数据库名字 44 | unsigned int _port; //mysql端口 45 | const char* _socket; //可以设置成Socket or Pipeline,通常设置为NULL 46 | unsigned long _client_flag; //设置为0 47 | unsigned int MAX_CONNECT; //同时允许最大连接对象数量 48 | unsigned int connect_count; //目前连接池的连接对象数量 49 | static std::mutex objectlock; //对象锁 50 | static std::mutex poollock; //连接池锁 51 | static MysqlPool* mysqlpool_object; //类的对象 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /mysqlpool/mysqlpool.cpp: -------------------------------------------------------------------------------- 1 | #include "include/mysqlpool.h" 2 | 3 | 4 | MysqlPool* MysqlPool::mysqlpool_object = NULL; 5 | std::mutex MysqlPool::objectlock; 6 | std::mutex MysqlPool::poollock; 7 | 8 | MysqlPool::MysqlPool() {} 9 | 10 | /* 11 | *配置数据库参数 12 | */ 13 | void MysqlPool::setParameter( const char* mysqlhost, 14 | const char* mysqluser, 15 | const char* mysqlpwd, 16 | const char* databasename, 17 | unsigned int port, 18 | const char* socket, 19 | unsigned long client_flag, 20 | unsigned int max_connect ) { 21 | _mysqlhost = mysqlhost; 22 | _mysqluser = mysqluser; 23 | _mysqlpwd = mysqlpwd; 24 | _databasename = databasename; 25 | _port = port; 26 | _socket = socket; 27 | _client_flag = client_flag; 28 | MAX_CONNECT = max_connect; 29 | } 30 | 31 | /* 32 | *有参的单例函数,用于第一次获取连接池对象,初始化数据库信息。 33 | */ 34 | MysqlPool* MysqlPool::getMysqlPoolObject() { 35 | if (mysqlpool_object == NULL) { 36 | objectlock.lock(); 37 | if (mysqlpool_object == NULL) { 38 | mysqlpool_object = new MysqlPool(); 39 | } 40 | objectlock.unlock(); 41 | } 42 | return mysqlpool_object; 43 | } 44 | 45 | /* 46 | *创建一个连接对象 47 | */ 48 | MYSQL* MysqlPool::createOneConnect() { 49 | MYSQL* conn = NULL; 50 | conn = mysql_init(conn); 51 | if (conn != NULL) { 52 | if (mysql_real_connect(conn, 53 | _mysqlhost, 54 | _mysqluser, 55 | _mysqlpwd, 56 | _databasename, 57 | _port, 58 | _socket, 59 | _client_flag)) { 60 | connect_count++; 61 | return conn; 62 | } else { 63 | std::cout << mysql_error(conn) << std::endl; 64 | return NULL; 65 | } 66 | } else { 67 | std::cerr << "init failed" << std::endl; 68 | return NULL; 69 | } 70 | } 71 | 72 | /* 73 | *判断当前MySQL连接池的是否空 74 | */ 75 | bool MysqlPool::isEmpty() { 76 | return mysqlpool.empty(); 77 | } 78 | /* 79 | *获取当前连接池队列的队头 80 | */ 81 | MYSQL* MysqlPool::poolFront() { 82 | return mysqlpool.front(); 83 | } 84 | /* 85 | * 86 | */ 87 | unsigned int MysqlPool::poolSize() { 88 | return mysqlpool.size(); 89 | } 90 | /* 91 | *弹出当前连接池队列的队头 92 | */ 93 | void MysqlPool::poolPop() { 94 | mysqlpool.pop(); 95 | } 96 | /* 97 | *获取连接对象,如果连接池中有连接,就取用;没有,就重新创建一个连接对象。 98 | *同时注意到MySQL的连接的时效性,即在连接队列中,连接对象在超过一定的时间后没有进行操作, 99 | *MySQL会自动关闭连接,当然还有其他原因,比如:网络不稳定,带来的连接中断。 100 | *所以在获取连接对象前,需要先判断连接池中连接对象是否有效。 101 | *考虑到数据库同时建立的连接数量有限制,在创建新连接需提前判断当前开启的连接数不超过设定值。 102 | */ 103 | MYSQL* MysqlPool::getOneConnect() { 104 | poollock.lock(); 105 | MYSQL *conn = NULL; 106 | if (!isEmpty()) { 107 | while (!isEmpty() && mysql_ping(poolFront())) { 108 | mysql_close(poolFront()); 109 | poolPop(); 110 | connect_count--; 111 | } 112 | if (!isEmpty()) { 113 | conn = poolFront(); 114 | poolPop(); 115 | } else { 116 | if (connect_count < MAX_CONNECT) 117 | conn = createOneConnect(); 118 | else 119 | std::cerr << "the number of mysql connections is too much!" << std::endl; 120 | } 121 | } else { 122 | if (connect_count < MAX_CONNECT) 123 | conn = createOneConnect(); 124 | else 125 | std::cerr << "the number of mysql connections is too much!" << std::endl; 126 | } 127 | poollock.unlock(); 128 | return conn; 129 | } 130 | /* 131 | *将有效的链接对象放回链接池队列中,以待下次的取用。 132 | */ 133 | void MysqlPool::close(MYSQL* conn) { 134 | if (conn != NULL) { 135 | poollock.lock(); 136 | mysqlpool.push(conn); 137 | poollock.unlock(); 138 | } 139 | } 140 | /* 141 | * sql语句执行函数,并返回结果,没有结果的SQL语句返回空结果, 142 | * 每次执行SQL语句都会先去连接队列中去一个连接对象, 143 | * 执行完SQL语句,就把连接对象放回连接池队列中。 144 | * 返回对象用map主要考虑,用户可以通过数据库字段,直接获得查询的字。 145 | * 例如:m["字段"][index]。 146 | */ 147 | std::map > MysqlPool::executeSql(const char* sql) { 148 | MYSQL* conn = getOneConnect(); 149 | std::map > results; 150 | if (conn) { 151 | if (mysql_query(conn,sql) == 0) { 152 | MYSQL_RES *res = mysql_store_result(conn); 153 | if (res) { 154 | MYSQL_FIELD *field; 155 | while ((field = mysql_fetch_field(res))) { 156 | results.insert(make_pair(field->name,std::vector())); 157 | } 158 | MYSQL_ROW row; 159 | while ((row = mysql_fetch_row(res))) { 160 | unsigned int i = 0; 161 | for (std::map >::iterator it = results.begin(); 162 | it != results.end(); ++it) { 163 | (it->second).push_back(row[i++]); 164 | } 165 | } 166 | mysql_free_result(res); 167 | } else { 168 | if (mysql_field_count(conn) != 0) 169 | std::cerr << mysql_error(conn) << std::endl; 170 | } 171 | } else { 172 | std::cerr << mysql_error(conn) <