Qt多线程访问数据库2

一般可用下面的函数创建和取得数据库连接:

void createConnectionByName(const QString &connectionName) 
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", connectionName);
    db.setHostName("127.0.0.1");
    db.setDatabaseName("qt"); // 如果是 SQLite 则为数据库文件名
    db.setUserName("root");   // 如果是 SQLite 不需要
    db.setPassword("root");   // 如果是 SQLite 不需要

    if(!db.open()) 
    {
        qDebug() << "Connect to MySql error: " << db.lastError().text();
        return;
    }
}

QSqlDatabase getConnectionByName(const QString &connectionName) 
{
    return QSqlDatabase::database(connectionName);
}

虽然抽象出了连接的创建和获取,但是有几个弊端:

  • 需要维护连接的名字
  • 获取连接的时候需要传入连接的名字
  • 获取连接的时候不知道连接是否已经被使用,使用多线程的时候,每个线程都必须使用不同的连接
  • 控制连接的最大数量比较困难,因为不能在程序里无限制的创建连接
  • 连接断了后不会自动重连
  • 删除连接不方便

这一节我们将创建一个简易的数据库连接池,就是为了解决上面的几个问题。使用数据库连接池后,只需要关心下面 3 个函数,而且刚刚提到的那些弊端都通过连接池解决了,对调用者是透明的。

功能 代码
获取连接 QSqlDatabase db = ConnectionPool::openConnection()
释放连接 ConnectionPool::closeConnection(db)
关闭连接池 ConnectionPool::release() // 一般在 main() 函数返回前调用

数据库连接池的使用

在具体介绍数据库连接池的实现之前,先来看看怎么使用。

#include "ConnectionPool.h"
#include <QDebug>

void foo() 
{
    // 1. 从数据库连接池里取得连接
    QSqlDatabase db = ConnectionPool::openConnection();

    // 2. 使用连接查询数据库
    QSqlQuery query(db);
    query.exec("SELECT * FROM user where id=1");

    while(query.next()) 
    {
        qDebug() << query.value("username").toString();
    }

    // 3. 连接使用完后需要释放回数据库连接池
    ConnectionPool::closeConnection(db);
}

int main(int argc, char *argv[]) 
{
    foo();

    ConnectionPool::release(); // 4. 释放数据库连接
    return 0;
}

数据库连接池的特点

  • 获取连接时不需要了解连接的名字
  • 支持多线程,保证获取到的连接一定是没有被其他线程正在使用
  • 按需创建连接
  • 可以创建多个连接
  • 可以控制连接的数量
  • 连接被复用,不是每次都重新创建一个新的连接
  • 连接断开了后会自动重连
  • 当无可用连接时,获取连接的线程会等待一定时间尝试继续获取,直到超时才会返回一个无效的连接
  • 关闭连接很简单

数据库连接池的实现

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

ConnectionPool.h

#ifndef CONNECTIONPOOL_H
#define CONNECTIONPOOL_H

#include <QtSql>
#include <QQueue>
#include <QString>
#include <QMutex>
#include <QMutexLocker>

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 Connec
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值