1.什么是数据库连接池
- 后台开发中常用的技术,在操作数据库之前,先要获得数据库连接,然后用数据库连接去进行数据库的增删改查等操作。建立连接和销毁连接都是一笔很大的性能开销,因此产生了连接池的技术。连接池与线程池一样,都是一种资源池,专门用于处理共享资源的。它可以维护一定数量的连接不销毁,当有连接申请时,从池中取出供客户使用;使用完毕则释放归还池中;当池中连接的数量不足时,还可以创建一部分连接。
- 减少建立连接与销毁连接的性能开销,避免频繁进行连接的建立与销毁,提升系统性能。
限制客户端向数据库发起的数据库访问,避免系统宕机,也避免过多的连接被直接拒绝。
2.C++代码实现
#ifndef_CONNECTION_POOL_H
#define _CONNECTION_POOL_H
#include<mysql_connection.h>
#include<mysql_driver.h>
#include<cppconn/exception.h>
#include<cppconn/driver.h>
#include<cppconn/connection.h>
#include<cppconn/resultset.h>
#include<cppconn/prepared_statement.h>
#include<cppconn/statement.h>
#include<pthread.h>
#include<list>
usingnamespace std;
usingnamespace sql;
classConnPool{
private:
intcurSize;
intmaxSize;
stringusername;
stringpassword;
stringurl;
list<Connection*>connList;
pthread_mutex_tlock;
staticConnPool *connPool;
Driver*driver;
Connection*CreateConnection();
voidInitConnection(int iInitialSize);
voidDestoryConnection(Connection *conn);
voidDestoryConnPool();
ConnPool(stringurl,string user,string password,int maxSize);
public:
~ConnPool();
Connection*GetConnection();
voidReleaseConnection(Connection *conn);
staticConnPool *GetInstance();
};
#endif
#include<stdexcept>
#include<exception>
#include<stdio.h>
#include"connection_pool.h"
usingnamespace std;
usingnamespace sql;
ConnPool*ConnPool::connPool=NULL;
ConnPool::ConnPool(stringurl, string userName,string password, int maxSize)
{
this->maxSize=maxSize;
this->curSize=0;
this->username=userName;
this->password=password;
this->url=url;
try{
this->driver=sql::mysql::get_driver_instance();
}
catch(sql::SQLException&e)
{
perror("驱动连接出错;\n");
}
catch(std::runtime_error&e)
{
perror("运行出错了\n");
}
this->InitConnection(maxSize/2);
}
ConnPool*ConnPool::GetInstance(){
if(connPool==NULL)
{
connPool=newConnPool("tcp://127.0.0.1:3306","root","root",50);
}
returnconnPool;
}
voidConnPool::InitConnection(int iInitialSize)
{
Connection*conn;
pthread_mutex_lock(&lock);
for(inti=0;i<iInitialSize;i++)
{
conn=this->CreateConnection();
if(conn){
connList.push_back(conn);
++(this->curSize);
}
else
{
perror("创建CONNECTION出错");
}
}
pthread_mutex_unlock(&lock);
}
Connection*ConnPool::CreateConnection(){
Connection*conn;
try{
conn=driver->connect(this->url,this->username,this->password);
returnconn;
}
catch(sql::SQLException&e)
{
perror("创建连接出错");
returnNULL;
}
catch(std::runtime_error&e)
{
perror("运行时出错");
returnNULL;
}
}
Connection*ConnPool::GetConnection(){
Connection*con;
pthread_mutex_lock(&lock);
if(connList.size()>0)
{
con=connList.front();
connList.pop_front();
if(con->isClosed())
{
deletecon;
con=this->CreateConnection();
}
if(con==NULL)
{
--curSize;
}
pthread_mutex_unlock(&lock);
returncon;
}
else{
if(curSize< maxSize){
con= this->CreateConnection();
if(con){
++curSize;
pthread_mutex_unlock(&lock);
returncon;
}
else{
pthread_mutex_unlock(&lock);
returnNULL;
}
}
else{
pthread_mutex_unlock(&lock);
returnNULL;
}
}
}
voidConnPool::ReleaseConnection(sql::Connection * conn){
if(conn){
pthread_mutex_lock(&lock);
connList.push_back(conn);
pthread_mutex_unlock(&lock);
}
}
ConnPool::~ConnPool()
{
this->DestoryConnPool();
}
voidConnPool::DestoryConnPool(){
list<Connection*>::iterator icon;
pthread_mutex_lock(&lock);
for(icon=connList.begin();icon!=connList.end();++icon)
{
this->DestoryConnection(*icon);
}
curSize=0;
connList.clear();
pthread_mutex_unlock(&lock);
}
voidConnPool::DestoryConnection(Connection* conn)
{
if(conn)
{
try{
conn->close();
}
catch(sql::SQLException&e)
{
perror(e.what());
}
catch(std::exception&e)
{
perror(e.what());
}
deleteconn;
}
}