C++数据库连接池设计与实现

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  /*_CONNECTION_POOL_H */  

#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  
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{//建立的连接数已经达到maxSize  
            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;  
    }  
}  

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值