qt mysql数据库 连接池_Qt C++ 数据库连接池

这篇博客介绍了如何在Qt中实现一个数据库连接池,强调了连接池在多线程环境中的重要性和特性,如按需创建连接、复用连接以及超时重连机制。尽管提供的代码示例不适用于多线程,但给出了改进的思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序资料来自网络, 不过这个广泛流传的资料 实际上 是不能 在多线程中使用的,因为对象不能跨线程, 想用在多线程或线程池中的话,必须要加以修改。

数据库连接池的特点

获取连接时不需要了解连接的名字

支持多线程,保证获取到的连接一定是没有被其他线程正在使用

按需创建连接

可以创建多个连接

可以控制连接的数量

连接被复用,不是每次都重新创建一个新的连接

连接断开了后会自动重连

当无可用连接时,获取连接的线程会等待一定时间尝试继续获取,

直到超时才会返回一个无效的连接 。

关闭连接很简单 。

程序文件

数据库连接池的实现只需要 2 个文件:ConnectionPool.h 和 ConnectionPool.cpp。下面会列出文件的内容加以介绍。

ConnectionPool.h 文件

#ifndef CONNECTIONPOOL_H

#define CONNECTIONPOOL_H

#include

#include

#include

#include

#include

class ConnectionPool {

public:

static void release(); // 关闭所有的数据库连接

static QSqlDatabase openConnection(); // 获取数据库连接

static void closeConnection(QSqlDatabase connection); // 释放数据库连接回连接池

~ConnectionPool();

private:

static ConnectionPool& getInstance();

ConnectionPool();

ConnectionPool(const ConnectionPool &other);

ConnectionPool& operator=(const ConnectionPool &other);

QSqlDatabase createConnection(const QString &connectionName); // 创建数据库连接

QQueue usedConnectionNames; // 已使用的数据库连接名

QQueue unusedConnectionNames; // 未使用的数据库连接名

// 数据库信息

QString hostName;

QString databaseName;

QString username;

QString password;

QString databaseType;

bool testOnBorrow; // 取得连接的时候验证连接是否有效

QString testOnBorrowSql; // 测试访问数据库的 SQL

int maxWaitTime; // 获取连接最大等待时间

int waitInterval; // 尝试获取连接时等待间隔时间

int maxConnectionCount; // 最大连接数

static QMutex mutex;

static QWaitCondition waitConnection;

static ConnectionPool *instance;

};

#endif // CONNECTIONPOOL_H

openConnection() 用于从连接池里获取连接。

closeConnection(QSqlDatabase connection) 并不会真正的关闭连接,而是把连接放回连接池复用。连接的底层是通过 Socket 来通讯的,建立 Socket 连接是非常耗时的,如果每个连接都在使用完后就给断开 Socket 连接,需要的时候再重新建立 Socket连接是非常浪费的,所以要尽量的复用以提高效率。

release() 真正的关闭所有的连接,一般在程序结束的时候才调用,在 main() 函数的 return 语句前。

usedConnectionNames 保存正在被使用的连接的名字,用于保证同一个连接不会同时被多个线程使用。

unusedConnectionNames 保存没有被使用的连接的名字,它们对应的连接在调用 openConnection() 时返回。

如果 testOnBorrow 为 true,则连接断开后会自动重新连接(例如数据库程序崩溃了,网络的原因等导致连接断开了)。但是每次获取连接的时候都会先查询一下数据库,如果发现连接无效则重新建立连接。testOnBorrow 为 true 时,需要提供一条 SQL 语句用于测试查询,例如 MySQL 下可以用 SELECT 1。如果 testOnBorrow 为 false,则连接断开后不会自动重新连接。需要注意的是,Qt 里已经建立好的数据库连接当连接断开后调用 QSqlDatabase::isOpen() 返回的值仍然是 true,因为先前的时候已经建立好了连接,Qt 里没有提供判断底层连接断开的方法或者信号,所以 QSqlDatabase::isOpen() 返回的仍然是先前的状态 true。

testOnBorrowSql 为测试访问数据库的 SQL,一般是一个非常轻量级的 SQL,如 SELECT 1。

获取连接的时候,如果没有可用连接,我们的策略并不是直接返回一个无效的连接,而是等待 waitInterval 毫秒,如果期间有连接被释放回连接池里就返回这个连接,没有就继续等待 waitInterval 毫秒,再看看有没有可用连接,直到等待 maxWaitTime 毫秒仍然没有可用连接才返回一个无效的连接。

因为我们不能在程序里无限制的创建连接,用 maxConnectionCount 来控制创建连接的最大数量。

这个程序用过之后 ,感觉挺好的。(除了在多线程中使用 要加以修改。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值