【数据库连接池】01:连接池初始化

连接池初始化


1.Connection类

封装Connection类,在该类内调用mysql提供的接口实现对数据库的增删改查,

Connection.h
#ifndef _CONNECTION_H
#define _CONNECTION_H

#include <string.h>
#include <iostream>
#include <mysql/mysql.h>
using namespace std;

#define LOG(str)									\
	cout << __FILE__ << ":" << __LINE__ << " " <<	\
	__TIMESTAMP__ << ":" << str << endl;

// 封装Connection对象 实现数据库增删改查
class Connection {
   
public:
	// 初始化数据库连接
	Connection();
    // 释放数据库连接资源
    ~Connection();
    // 连接数据库
    bool connect(string ip, unsigned short port, string user, string password, string dbname);
    // 更新数据库操作 insert delete update
    bool update(string sql);
private:
    // 表示和 MYSQL Server的一条连接
    MYSQL *_conn;
};

#endif
Connection.cpp
#include "Connection.h"

Connection::Connection()
{
   
	_conn = mysql_init(nullptr);
}

Connection::~Connection()
{
   
	if (_conn != nullptr) mysql_close(_conn);
}

bool Connection::connect(string ip, unsigned short port, string user, string password, string dbname)
{
   
	MYSQL *p = mysql_real_connect(_conn, ip.c_str(), user.c_str(), password.c_str(), dbname.c_str(), port, nullptr, 0);
	return p != nullptr;
}

// insert delete update
bool Connection::update(string sql)
{
   
	if (mysql_query(_conn, sql.c_str())) {
   
		LOG("update failed!~" + sql);
		return false;
	}
	return mysql_use_result(_conn);
}

2.CommonConnectionPool类

  • 需求分析:

    在整个系统中数据库连接池对象出现一次即可,有数据库连接需求时,从同一个数据库连接池中获取 Connection 对象即可,

    连接池不需要创建多个,所以可以通过单例模式来设计数据库连接池类,但是服务器肯定是多线程的,肯定会有多个线程都来获取连接池的单例,所以还需要保证数据库连接池的线程安全问题,

  • CommonConnectionPool类设计:需要通过单例模式实现,并保证数据库连接池的线程安全问题(线程安全的单例),

  • 功能实现:启动连接池构造函数,读取基本的配置文件、初始化连接池数量initSize

CommonConnectionPool.h
#ifndef _COMMONCONNECTIONPOOL_H
#define _COMMONCONNECTIONPOOL_H

#include <queue>
#include <string>
#include <mutex>
#include <atomic>
#include <thread>
#include "Connection.h"
using namespace std;

// 实现连接池功能模块
class ConnectionPool {
   
public:
	static ConnectionPool* getConnectionPool();
private:
	ConnectionPool();
	bool loadConfigFile();
	// 连接池参数
	int _initSize;				// 初始连接量
	int _maxSize;				// 最大连接量
	int _maxIdleTime;			// 最大空闲时间
	int _connectionTimeout;		// 连接超时时间
	// 数据库信息
	string _ip;
	unsigned short _port;
	string _username;
	string _password;
	string _dbname;
	// 数据库连接存储
	queue<Connection*> _connectionq;		// 存储mysql连接的队列
	mutex _queueMutex;						// 维护连接队列的线程安全的互斥锁
	atomic_int _connectionCnt;				// 创建连接的数量 ++操作是线程安全的
};

#endif
CommonConnectionPool.cpp
#include "public.h"
#include "CommonConnectionPool.h"

// 懒汉单例模式
// 对于静态局部变量的初始化 由编译器自动进行 lock与unlock
ConnectionPool* ConnectionPool::getConnectionPool()
{
   
	static ConnectionPool pool;
    return &pool;
}

// 初始化连接池
ConnectionPool::ConnectionPool() {
   
	// 1.加载配置项
	if (!loadConfigFile()) return;
	// 2.创建初始数量的连接
	for (int i = 0; i < _initSize; ++i) {
   
		Connection *p = new Connection();
		p->connect(_ip, _port, _username, _password, _dbname);
		_connectionq.push(p);
		_connectionCnt++;
	}
	// 3.启动一个新的线程作为连接的生产者
}

// 读取配置文件
bool ConnectionPool::loadConfigFile()
{
   
	FILE *fp = fopen("config.conf", "r");
	if (fp == nullptr) {
   
		LOG("Config file error, file not exists!");
		return false;
	}
	while (!feof(fp)) {
   
		// 逐行读取配置文件
		char line[1024] = {
    0 };
		fgets(line, 1024, fp);
		string str = line;
		// 查找配置项
		int idx = str.find('=', 0);
		if (idx == -1) continue;// 无效配置项
		int edx = str.find('\n', 0);
		string key = str.substr(0, idx);
		string value = str.substr(idx + 1, edx - idx - 1);
		// 初始化成员变量
		if (key == "ip") {
   
			_ip = value;
		} else if (key == "port") {
   
			_port = atoi(value.c_str());
		} else if (key == "username") {
   
			_username = value;
		} else if (key == "password") {
   
			_password = value;
		} else if (key == "dbname") {
   
			_dbname = value;
		} else if (key == "initSize") {
   
			_initSize = atoi(value.c_str());
		} else if (key == "maxSize") {
   
			_maxSize = atoi(value.c_str());
		} else if (key == "maxIdleTime") {
   
			_maxIdleTime = atoi(value.c_str());
		} else if (key == "connectionTimeout") {
   
			_connectionTimeout = atoi(value.c_str());
		}
	}
	return true;
}

相关推荐

  1. 数据库连接01连接初始化

    2023-12-05 22:54:02       37 阅读
  2. JDBC数据库连接

    2023-12-05 22:54:02       38 阅读
  3. C++数据库连接

    2023-12-05 22:54:02       37 阅读
  4. 【JDBC】数据库连接

    2023-12-05 22:54:02       12 阅读
  5. 数据库连接详解

    2023-12-05 22:54:02       32 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-05 22:54:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-05 22:54:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-05 22:54:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-05 22:54:02       20 阅读

热门阅读

  1. Go查询Elasticsearch

    2023-12-05 22:54:02       39 阅读
  2. Python 3 使用 write()、writelines() 函数写入文件

    2023-12-05 22:54:02       33 阅读
  3. ClickHouse:真正的OLAP列式DBMS

    2023-12-05 22:54:02       42 阅读
  4. npm私仓 verdaccio搭建 & 发布到私仓 使用

    2023-12-05 22:54:02       30 阅读
  5. ElasticSearch之Force merge API

    2023-12-05 22:54:02       41 阅读
  6. Git多库多账号本地SSH连接配置方法

    2023-12-05 22:54:02       46 阅读
  7. npm run build打包jquery项目

    2023-12-05 22:54:02       34 阅读
  8. macOS/Ubuntu - ftp 工具

    2023-12-05 22:54:02       130 阅读
  9. Python与ArcGIS系列(十三)UpdateCursor方法

    2023-12-05 22:54:02       38 阅读
  10. Python与ArcGIS系列(十二)InsertCursor方法

    2023-12-05 22:54:02       34 阅读
  11. golang 集成logrus日志框架

    2023-12-05 22:54:02       38 阅读
  12. tcexam 本地容器化搭建

    2023-12-05 22:54:02       43 阅读
  13. ClickHouse入门手册1.0

    2023-12-05 22:54:02       32 阅读
  14. 西南科技大学(数据结构A)期末自测练习四

    2023-12-05 22:54:02       33 阅读