`
suiyuan0808
  • 浏览: 154441 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Linux下C++访问MySQL连接池<二>

    博客分类:
  • c++
阅读更多

实现是基于mysql connector C++ api的

connpool.h文件

 /**
  *数据库连接池(单例模式)
  **/
#ifndef CONN_POOL_H
#define CONN_POOL_H

#include <mysql_connection.h>
#include <mysql_driver.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include "push.h"
#include "mutex.h"
    
using namespace std;

class ConnPool{
    private:
        deque<sql::Connection *> conns;//连接队列
        int curSize;//当前队列中路连接数目
        int maxSize;//最大连接数目
        sql::ConnectOptionsMap connectionProperties;
        Mutex *lock;//连接队列互斥锁
        static ConnPool * connPool;
        sql::Driver * driver;//mysql connector C++ driver
        sql::Connection * CreateConnection();//创建一个连接
        void TerminateConnection(sql::Connection * conn);//终止一个连接
        void Init(int initialSize);//初始化连接池
        void Destroy();//销毁连接池
    protected:
        ConnPool(string host,string user,string password,int maxSize);
    public:
        ~ConnPool();
        sql::Connection * GetConnection();//获取一个连接
        void ReleaseConnection(sql::Connection * conn);//释放一个连接
        sql::Connection * GetConnectionTry(int maxNum);//GetConnection的加强版,maxNum代表重试次数
        static ConnPool * GetInstance();//获取一个ConnPool对象实例
};

#endif
   

connpool.cpp文件

/**
  *数据库连接池
  *  **/
#include <stdexcept>
#include "connpool.h"
#include "config.h"
            
using namespace std;
extern Config *config;

ConnPool * ConnPool::connPool = NULL;

ConnPool::ConnPool(string host,string user,string password,int maxSize){
    connectionProperties["hostName"] = host;
    connectionProperties["userName"] = user;
    connectionProperties["password"] = password;
    connectionProperties["OPT_CONNECT_TIMEOUT"] = 600;
    connectionProperties["OPT_RECONNECT"] = true;
    
    this->maxSize = maxSize;
    this->lock = new Mutex();
    this->curSize = 0;
    //初始化driver
    try{
        this->driver = sql::mysql::get_driver_instance();  //这里不是线程安全的
    }
    catch(sql::SQLException &e){
        string errorMsg = string("SQLException: ") + e.what() + string(" MySQL error code: ") + int_to_string(e.getErrorCode()) + string(" SQLState ") +  e.getSQLState();
        Log::Write(__FILE__,__FUNCTION__,__LINE__,errorMsg);
    }
    catch(std::runtime_error &e){
        string errorMsg = string("runtime_error: ") + e.what();
        Log::Write(__FILE__,__FUNCTION__,__LINE__,errorMsg);
    }
    //初始化连接池
    this->Init(maxSize/2);
}

ConnPool::~ConnPool(){    
    this->Destroy();
    delete lock;
}

ConnPool *ConnPool::GetInstance(){
    if(connPool == NULL) {
        connPool = new ConnPool(config->GetVar("db_host"),config->GetVar("db_user"),config->GetVar("db_password"),string_to_int(config->GetVar("max_db_conn_size")));
    }
    
    return connPool;
}

void ConnPool::Init(int size){
    sql::Connection * conn ;
    lock->Lock();
    
    for(int i = 0; i < size ;){
        conn = this->CreateConnection();
        if(conn){
            i++;            
            conns.push_back(conn);
            ++curSize;
        }
        else{
            Log::Write(__FILE__,__FUNCTION__,__LINE__,"Init connpooo fail one");
        }
    }
    
    lock->UnLock();    
}

void ConnPool::Destroy(){
    deque<sql::Connection *>::iterator pos;
    
    lock->Lock();
    
    for(pos = conns.begin(); pos != conns.end();++pos){
        this->TerminateConnection(*pos);
    }
    
    curSize = 0;
    conns.clear();
    
    lock->UnLock();    
}

sql::Connection * ConnPool::CreateConnection(){//这里不负责curSize的增加
    sql::Connection *conn;
    
    try{
        conn = driver->connect(connectionProperties);
        Log::Write(__FILE__,__FUNCTION__,__LINE__,"create a mysql conn");
        return conn;
    }
    catch(sql::SQLException &e){
        string errorMsg = string("SQLException:") + e.what() + string(" MySQL error code: ") + int_to_string(e.getErrorCode()) + string(" SQLState ") +  e.getSQLState();
        Log::Write(__FILE__,__FUNCTION__,__LINE__,errorMsg);
        return NULL;
    }
    catch(std::runtime_error &e){
        string errorMsg = string("runtime_error: ") + e.what();
        Log::Write(__FILE__,__FUNCTION__,__LINE__,errorMsg);
        return NULL;
    }
}

void ConnPool::TerminateConnection(sql::Connection * conn){
    if(conn){
        try{
            conn->close();
        }
        catch(sql::SQLException &e){
            string errorMsg = string("SQLException:") + e.what() + string(" MySQL error code: ") + int_to_string(e.getErrorCode()) + string(" SQLState ") +  e.getSQLState();
            Log::Write(__FILE__,__FUNCTION__,__LINE__,errorMsg);
        }
        catch(std::runtime_error &e){
            string errorMsg = string("runtime_error: ") + e.what();
            Log::Write(__FILE__,__FUNCTION__,__LINE__,errorMsg);
        }
        
        delete conn;
    }
}

sql::Connection * ConnPool::GetConnection(){
    sql::Connection * conn;
    
    lock->Lock();
    
    if(conns.size() > 0){//有空闲连接,则返回
        conn = conns.front();
        conns.pop_front();
        
        if(conn->isClosed()){ //如果连接关闭,则重新打开一个连接
            Log::Write(__FILE__,__FUNCTION__,__LINE__,"a mysql conn has been closed");
            delete conn;
            conn = this->CreateConnection();
        }
        
        if(conn == NULL){ //创建连接不成功
            --curSize;
        }
        lock->UnLock();
        
        return conn;
    }
    else{
        if(curSize < maxSize){//还可以创建新的连接
            conn = this->CreateConnection();
            if(conn){
                ++curSize;
                lock->UnLock();
                return conn;
            }
            else{
                lock->UnLock();
                return NULL;
            }
        }
        else{//连接池已经满了
            lock->UnLock();
            return NULL;
        }
    }    
}

void ConnPool::ReleaseConnection(sql::Connection * conn){
    if(conn){
        lock->Lock();
        
        conns.push_back(conn);
        
        lock->UnLock();
    }
}

sql::Connection * ConnPool::GetConnectionTry(int maxNum){
    sql::Connection * conn;
    
    for(int i = 0; i < maxNum; ++i){
        conn = this->GetConnection();
        if(conn){
            return conn;
        }
        else {
            sleep(2);
        }
    }
    
    return NULL;
}

分享到:
评论
1 楼 wxqhbw2008 2012-10-26  
我刚学c++,这个connpool.h文件copy过去就报错,报以下这些头文件无法打开,这些头文件是怎么回事呀,不太懂
#include <mysql_connection.h>
#include <mysql_driver.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include "push.h"
#include "mutex.h"
谢谢提点

相关推荐

    mysql5.1中文手册

    在Linux下安装MySQL&lt;br&gt;2.5.在Mac OS X中安装MySQL&lt;br&gt;2.6. 在NetWare中安装MySQL&lt;br&gt;2.7. 在其它类Unix系统中安装MySQL&lt;br&gt;2.8. 使用源码分发版安装MySQL&lt;br&gt;2.8.1. 源码安装概述&lt;br&gt;2.8.2. 典型配置选项&lt;br&gt;2.8.3...

    linux(centos) 下C++连接mysql数据库

    在Linux(CentOS)系统中,使用C++连接MySQL数据库是一项常见的任务,特别是在开发服务器端应用程序时。这里我们将深入探讨如何实现这一目标,以及在这个过程中可能遇到的关键知识点。 首先,你需要确保你的系统...

    linux C/C++ 数据库连接池

    在Linux环境下,C/C++开发数据库连接池是提高应用程序性能和效率的重要技术。数据库连接池是一种管理数据库连接的机制,它允许程序重复使用已建立的数据库连接,而不是每次需要时都创建新的连接。这减少了创建和销毁...

    linux下C++连接数据库程序源码附加编译命令

    在Linux环境下,使用C++进行数据库编程是一项常见的任务,它涉及到多方面的技术,包括数据库API的使用、编译环境的配置以及程序的构建过程。本文将深入探讨如何在Linux下用C++编写连接数据库的程序,并附上编译命令...

    在Linux环境下使用C++ 11开发的MySQL连接池,可以节省创建MySQL连接的时间,加速访问数据

    wireshark在Linux环境下使用C++ 11开发的MySQL连接池,可以节省创建MySQL连接的时间,加速访问数据库。_MysqlPool.zip

    Mysql 连接(linux ,c++,java)

    安装此库后,可以使用`#include &lt;mysql_driver.h&gt;`和`#include &lt;mysql_connection.h&gt;`头文件来访问必要的API。连接过程包括以下步骤: 1. 初始化连接池或单个连接对象。 2. 创建一个`sql::mysql::MySQL_Driver`实例...

    linux系统C++操作mysql数据库

    - 使用MySQL Connector/C++,首先需包含头文件`#include &lt;mysql_driver.h&gt;`和`#include &lt;mysql_connection.h&gt;`。 - 创建`sql::mysql::MySQL_Driver`实例并获取连接器,然后使用`connect()`方法创建一个`sql::...

    c++连接mysql 例子和类

    安装后,库文件通常位于`&lt;mysql-connector-c++-version&gt;/include`和`&lt;mysql-connector-c++-version&gt;/lib`目录下。在VS2008中,你需要将这些路径添加到项目的包含目录和库目录设置中。 接下来,我们来看一个简单的...

    c++ 连接mysql 跨平台

    除了直接使用MySQL C API,还可以借助第三方库,如cppconn(MySQL Connector/C++),它提供了一个更现代、面向对象的接口,简化了数据库操作,并提供了更多的功能,如自动处理结果集、事务管理和连接池。...

    c++封装MYSQL数据库连接代码

    1. **C++与MySQL连接库**:MySQL为C++提供了一个名为`mysqlcppconn`的库,它允许开发者使用C++接口来操作MySQL数据库。这个库包含了`mysql.h`头文件和对应的动态或静态链接库文件,例如`libmysqlcppconn.so`(Linux...

    c++ mysqlhelper 数据库访问层功能封装

    1. 数据库连接相关的成员变量,如`MYSQL*`类型的指针,用于存储MySQL连接句柄。 2. 构造函数,用于初始化成员变量,如设置默认的数据库连接参数(主机名、用户名、密码、数据库名和端口号)。 3. 连接函数,用于建立...

    基于C++11和Linux环境的自写数据库连接池源码+项目说明.zip

    【项目介绍】基于C++11和Linux环境的自写数据库连接池源码+项目说明.zip关键技术要点- MySQL数据库编程- 设计模式中的单例模式- STL中的queue队列容器- C++11多线程编程- C++11线程互斥、线程同步通信和unique_lock-...

    Linux下实现C++操作Mysql数据库

    在Linux环境下,使用C++操作MySQL数据库是一种常见的需求,特别是在开发跨平台的应用程序时。本文将详细介绍如何通过MySQL的C API来实现这一功能。 首先,连接MySQL数据库的关键函数是`mysql_real_connect()`。这个...

    mysql访问类 c++封装,linux平台和windows平台下都可用

    在Linux和Windows平台上都能使用的C++ MySQL访问类,意味着该封装库考虑了跨平台兼容性。这通常涉及到使用条件编译指令(如`#ifdef`)来处理不同操作系统下的差异,比如文件路径、线程库和动态链接库的加载方式。...

    基于C++11和Linux环境的自写数据库连接池项目源码+文档说明.zip

    基于C++11和Linux环境的自写数据库连接池项目源码+文档说明.zip 【说明】 【1】项目代码完整且功能都验证ok,确保稳定可靠运行后才上传。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通,帮助解答。 ...

    mysql c++ 封装类

    MySQL C++ 封装类是将MySQL数据库的接口与C++编程语言相结合,提供一个更加友好、方便的接口供开发者使用...在实际应用中,可能还需要考虑更多因素,如事务管理、连接池、异步操作等,以适应不同的系统架构和性能需求。

    使用C和C++连接MySQL数据库并进行常用的数据库操作。

    在实际项目中,为了使代码更健壮,我们会封装这些基本操作,例如创建数据库连接池,定义查询和结果处理的类等。同时,注意处理可能出现的网络延迟、超时和异常情况。 例如,一个简单的C++连接MySQL并执行查询的示例...

    Mysql标准c++封装

    MySQL标准C++封装是将MySQL数据库的访问功能与C++编程语言相结合的一种技术,使得开发者可以使用C++的语法和特性来操作MySQL数据库。在Ubuntu操作系统下,这种封装经过了测试,确保了其在Linux环境中的兼容性和稳定...

    libzdb 数据库连接池

    Libzdb是一个专为Linux环境设计的数据库连接池库,它的主要功能是提供高效、稳定的数据库连接管理服务,适用于多种类型的数据库系统。Libzdb的强大之处在于它不仅支持常见的MySQL,还支持Oracle、SQLite和PostgreSQL...

    Poco访问数据库(测试例子MySQl)

    在本文中,我们将深入探讨如何使用Poco库访问MySQL数据库,这是一个C++开发中的常见任务。Poco是一个轻量级、跨平台的开源C++库,提供了多种功能,包括网络、数据存取、XML解析、JSON处理等。在这个测试例子中,我们...

Global site tag (gtag.js) - Google Analytics