提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 校验 & 数据库连接池
- 一、头文件
- 二、connectionRAII类
- 1.类的定义
- 2.构造函数与析构函数
- 二、connection_pool类
- 1.类的定义
- 2.构造函数与析构函数
- 3.GetInstance()
- 4.init()
- 5.GetConnection()
- 6.ReleaseConnection()
- 7.GetFreeConn()
- 8.DestroyPool()
- --------
- 1.引入库
- 2.读入数据
- 总结
校验 & 数据库连接池
数据库连接池
- 单例模式,保证唯一
- list实现连接池
- 连接池为静态大小
- 互斥锁实现线程安全
校验
- HTTP请求采用POST方式
- 登录用户名和密码校验
- 用户注册及多线程注册安全
共两个个class,分别是connection_pool和connectionRAII
一、头文件
#include
#include -
#include
#include #include #include #include #include "../lock/locker.h" #include "../log/log.h" using namespace std; 二、connectionRAII类
- RAII(Resource Acquisition Is Initialization)即资源获取即初始化,是一种C++编程技巧,用于管理资源。connectionRAII类依托于connection_pool类,用于在函数执行期间自动申请连接和自动释放连接,避免了手动申请和释放资源出现的错误和异常情况;
- 在创建connectionRAII对象时,它会自动调用connection_pool的GetConnection()方法来获取数据库连接;
- 在connectionRAII对象生命周期结束时,它会自动调用connection_pool的ReleaseConnection()方法来释放数据库连接。
1.类的定义
class connectionRAII{ public: connectionRAII(MYSQL **con, connection_pool *connPool); ~connectionRAII(); private: MYSQL *conRAII; connection_pool *poolRAII; };
2.构造函数与析构函数
构造函数,用于管理MySQL数据库连接的,采用资源获取即初始化(RAII)的方式进行自动化管理
在创建connectionRAII对象时,会自动获取一个数据库连接,并将其保存在conRAII中,同时也保存了连接池的指针,方便之后的释放操作
// 两个参数分别是:MYSQL类型的指针SQL和connection_pool类型的指针connPool connectionRAII::connectionRAII(MYSQL **SQL, connection_pool *connPool){ *SQL = connPool->GetConnection();// 将从连接池中获取到的一个数据库连接赋值给SQL指向的内存空间 conRAII = *SQL;// 将SQL所指向的内存空间的内容赋值给了conRAII成员变量 poolRAII = connPool;// 将connPool所指向的内存空间的内容赋值给了poolRAII成员变量 }
析构函数,用于释放数据库连接资源。在connectionRAII对象被销毁时(例如,作用域结束或delete运算符调用),会自动调用该析构函数
在connectionRAII对象被销毁时,会自动释放其所持有的数据库连接,避免了内存泄漏等问题。同时,由于使用了connection pool,还可以提高程序的效率,避免频繁创建和销毁数据库连接带来的开销
connectionRAII::~connectionRAII(){ poolRAII->ReleaseConnection(conRAII); }
二、connection_pool类
- 维护一个MySQL连接池,提供获取和释放连接的方法;
- 可以初始化连接池参数,包括URL、用户名、密码、数据库名、端口号、最大连接数等;
- 实现了单例模式,确保只有一个连接池实例存在;
- 通过使用锁和信号量控制并发访问连接池的线程安全问题。
1.类的定义
class connection_pool { public: MYSQL *GetConnection(); //获取数据库连接 bool ReleaseConnection(MYSQL *conn); //释放连接 int GetFreeConn(); //获取连接 void DestroyPool(); //销毁所有连接 //单例模式 static connection_pool *GetInstance(); void init(string url, string User, string PassWord, string DataBaseName, int Port, int MaxConn, int close_log); private: connection_pool(); ~connection_pool(); int m_MaxConn; //最大连接数 int m_CurConn; //当前已使用的连接数 int m_FreeConn; //当前空闲的连接数 locker lock; list
connList; //连接池 sem reserve; public: string m_url; //主机地址 string m_Port; //数据库端口号 string m_User; //登陆数据库用户名 string m_PassWord; //登陆数据库密码 string m_DatabaseName; //使用数据库名 int m_close_log; //日志开关 }; 2.构造函数与析构函数
构造函数,成员变量m_CurConn和m_FreeConn被初始化为0
connection_pool::connection_pool() { m_CurConn = 0; //当前已使用的连接数 m_FreeConn = 0; //当前空闲的连接数 }
析构函数,对连接池进行释放
connection_pool::~connection_pool() { DestroyPool(); }
3.GetInstance()
在整个应用程序中,只需要调用GetInstance()方法获取该连接池的唯一实例,然后就可以使用该实例执行数据库操作
connection_pool *connection_pool::GetInstance() { // static确保整个应用程序中只有一个数据库连接池 static connection_pool connPool; return &connPool; }
4.init()
用于初始化连接池
在整个程序生命周期中,只需要调用一次init()函数,就可以初始化连接池,然后在需要访问数据库时,从连接池中获取连接,执行完操作后,将连接归还到连接池中以供下次使用
void connection_pool::init(string url, string User, string PassWord, string DBName, int Port, int MaxConn, int close_log) { // 将传入参数赋值给成员变量 m_url = url; m_Port = Port; m_User = User; m_PassWord = PassWord; m_DatabaseName = DBName; m_close_log = close_log; // 创建了指定数量的数据库连接,并将连接添加到connList列表中 for (int i = 0; i < MaxConn; i++) { MYSQL *con = NULL; con = mysql_init(con); // 如果连接创建失败,则会输出错误信息并立即退出程序 if (con == NULL) { LOG_ERROR("MySQL Error"); exit(1); } // 创建mysql连接 con = mysql_real_connect(con, url.c_str(), User.c_str(), PassWord.c_str(), DBName.c_str(), Port, NULL, 0); // 如果连接创建失败,则会输出错误信息并立即退出程序 if (con == NULL) { LOG_ERROR("MySQL Error"); exit(1); } // 如果成功创建连接,则将连接添加到connList列表中 connList.push_back(con); // 并将m_FreeConn计数器加1,表示新增一个可用连接 ++m_FreeConn; } // 创建了一个名为reserve的信号量,初始值为m_FreeConn,表示当前空闲连接数 reserve = sem(m_FreeConn); // m_MaxConn变量被设置为m_FreeConn,表示最大连接数也是当前可用连接数 m_MaxConn = m_FreeConn; }
5.GetConnection()
数据库连接池中获取可用连接的函数。当有请求时,它会从数据库连接池(connList)中返回一个可用连接(con),并更新使用和空闲连接数
//当有请求时,从数据库连接池中返回一个可用连接,更新使用和空闲连接数 MYSQL *connection_pool::GetConnection() { MYSQL *con = NULL; // 检查连接池中是否有可用连接,如果没有则返回NULL表示没有可用连接 if (0 == connList.size()) return NULL; // 在没有可用连接的情况下会将线程阻塞以等待可用连接 reserve.wait(); lock.lock(); // 从连接池的头部取出一个连接 con = connList.front(); // 同时从连接池中移除该连接 connList.pop_front(); // 更新连接池中的空闲和正在使用的连接数 --m_FreeConn; ++m_CurConn; lock.unlock(); // 返回获取到的可用连接 return con; }
6.ReleaseConnection()
释放当前使用的连接
数据库连接池中释放连接的函数。当使用完一个连接后,可以通过调用该函数将该连接释放回连接池,并更新使用和空闲连接数
bool connection_pool::ReleaseConnection(MYSQL *con) { // 检查传入的参数con是否为空指针,如果是则直接返回false表示释放失败 if (NULL == con) return false; lock.lock(); // 将连接con添加到连接池的尾部 connList.push_back(con); // 更新连接池中的空闲和正在使用的连接数 ++m_FreeConn; --m_CurConn; lock.unlock(); // 调用reserve.post()方法,这个方法会通知之前被阻塞的线程,告诉它们当前有可用连接了,以便它们能够从连接池中获取连接 reserve.post(); return true; }
7.GetFreeConn()
返回当前空闲的连接数
数据库连接池中获取当前空闲连接数的函数。它直接返回连接池对象中的m_FreeConn成员变量,该变量记录了当前连接池中的空闲连接数量
int connection_pool::GetFreeConn() { return this->m_FreeConn; }
8.DestroyPool()
销毁数据库连接池
数据库连接池中销毁连接池的函数。当不再需要使用连接池时,可以通过调用该函数来销毁连接池,并释放已分配的资源
void connection_pool::DestroyPool() { lock.lock(); // 检查连接池中是否还有连接 if (connList.size() > 0) { list
::iterator it; // 遍历所有连接并调用mysql_close()方法关闭连接,释放资源 for (it = connList.begin(); it != connList.end(); ++it) { MYSQL *con = *it; mysql_close(con); } // 将连接池中的m_CurConn和m_FreeConn成员变量都置为0,表示当前没有任何连接在使用或者空闲 m_CurConn = 0; m_FreeConn = 0; // 调用connList.clear()方法清空连接池中的连接列表 connList.clear(); } lock.unlock(); } --------
1.引入库
代码如下(示例):
2.读入数据
代码如下(示例):
data = pd.read_csv( 'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv') print(data.head())
该处使用的url网络请求的数据。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
还没有评论,来说两句吧...