MySQL连接池

当程序中频繁访问数据库时,我们可以采用向内存池、线程池那样的池化技术,引入数据库连接池,减少申请和释放数据库连接的操作,从而提高性能。

在很多C++库中都集成了连接池,下面以Poco的mysql连接池为例进行简要的介绍,下面是代码示例,其他数据库连接池的使用也是类似。需要指定数据库连接的参数、最大最小连接数还有空闲时间。

#include <iostream>
#include "Poco/Data/MySQL/Connector.h"
#include "Poco/Data/MySQL/MySQLException.h"
#include "Poco/Data/SessionPool.h"
#include "Poco/Exception.h"
using namespace std;
using namespace Poco::Data::MySQL;
using namespace Poco::Data;
using namespace Poco;
using namespace Poco::Data::Keywords;

int main(int argc, char const* argv[]) {
    Poco::Data::MySQL::Connector::registerConnector();

    // 数据库配置参数
    std::string g_db_info =
        "host=localhost;port=3306;user=root;password=111111;db=testdb;"
        "compress=true;auto-reconnect=true";

    // 数据库连接池
    // 这里设置连接池最小回话数量为8,最大回话数量为128
    // 空闲时间为10秒,如果在连接池中空闲时间超过10秒则被回收
    Poco::Data::SessionPool* session_pool = new Poco::Data::SessionPool(
        Poco::Data::MySQL::Connector::KEY, g_db_info, 8, 128, 10);

    int count = 100;
    while (count--) {
        try {
            // Session session(Poco::Data::MySQL::Connector::KEY, g_db_info);
            Session session(session_pool->get());  // 从连接池中获取一个session
            std::string student_id("001");
            std::string name;
            session << "SELECT student_name from student where student_id = ?",
                use(student_id), into(name), now;
            std::cout << "name:" << name << std::endl;
            session.close();  // <推荐> 显式关闭连接
        } catch (Exception& e) {
            std::cerr << e.displayText() << std::endl;
        }
    }

    delete session_pool;
    Poco::Data::MySQL::Connector::unregisterConnector();
    return 0;
}

一般我们会把数据库连接池封装成一个全局的单例类来使用,如下

MysqlSessionPool.h

 

#pragma once
#include <cassert>
#include <string>

#include "Poco/Data/MySQL/Connector.h"
#include "Poco/Data/MySQL/MySQLException.h"
#include "Poco/Data/SessionPool.h"
#include "Poco/Exception.h"

using namespace Poco::Data::MySQL;
using namespace Poco::Data;
using namespace Poco;
using namespace std;

class MysqlSessionPool {
   private:
    Poco::Data::SessionPool* _session_pool = nullptr;
    const std::string _db_info;
    static const int _min_sessions = 1;
    static const int _max_sessions = 32;
    static const int _idle_time = 128;

   public:
    MysqlSessionPool()
        : _db_info(
              "host=localhost;port=3306;user=root;password=111111;db=testdb;"
              "compress=true;auto-reconnect=true") {
        Poco::Data::MySQL::Connector::registerConnector();
        _session_pool = new Poco::Data::SessionPool(
            Poco::Data::MySQL::Connector::KEY, _db_info, _min_sessions,
            _max_sessions, _idle_time);
        assert(_session_pool != nullptr);
    }

    ~MysqlSessionPool() {
        delete _session_pool;
        // Poco::Data::MySQL::Connector::unregisterConnector();
    }

    Session get() { return _session_pool->get(); }

    static MysqlSessionPool* GetInst();  //单例
};

MysqlSessionPool.cpp 这里用到poco的单例模板,用法比较简单,普通类成员增加一个静态函数即可。 然后用模板SingletonHolder定义一个holder即可。

#include "MysqlSessionPool.h"

#include "Poco/SingletonHolder.h"
using Poco::SingletonHolder;

static SingletonHolder<MysqlSessionPool> holder;
MysqlSessionPool* MysqlSessionPool::GetInst() { return holder.get(); }

调用

int main(int argc, char const* argv[]) {
    int count = 100;
    while (count--) {
        try {
            // 从连接池中获取一个session
            Session session(MysqlSessionPool::GetInst()->get());
            std::string student_id("001");
            std::string name;
            session << "SELECT student_name from student where student_id = ?",
                use(student_id), into(name), now;
            std::cout << "name:" << name << std::endl;
            session.close();  // <推荐> 显式关闭连接
        } catch (Exception& e) {
            std::cerr << e.displayText() << std::endl;
        }
    }

    return 0;
}

如果业务频繁访问数据库,而连接得不到及时的释放,那对数据库而言可能是一种灾难,有大量的数据库连接处于timewait状态,而这些连接资源是有限的。引入连接池之后,就可以避免这种问题,不过尽管我们设置了空闲时间,但是还是建议使用完毕之后,立刻显示的关闭数据库连接,这样才是最高效的。

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值