多线程里使用数据库——QtWidgets

前言

之前没怎么在项目中使用数据库,对数据库这块只了解一点皮毛,只能说能用。这次涉及了在多线程中使用数据库,看了看源码,和吸取了网上的一些经验,整理封装了一下。

环境

Qt5.15.2

QSqlDatabase原理

因为不太懂数据库连接的使用,就看了源码(Qt5.15.2版本源码),只是简单的看了一下,了解到:数据库连接是保存在一个容器中,可以称之为数据库连接池,它负责分配、管理和释放连接。这样的话,就可以重复使用数据库连接,而不需每次创建新的连接。

创建连接

创建连接源码如下,QConnectionDict 为所说的连接池,在添加连接之前使用了锁(QWriteLocker locker(&dict->lock);),所以它是线程安全的。若是连接名重复,会先移除之前的连接,再添加新的连接。

QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName)
{
    QSqlDatabase db(type);
    QSqlDatabasePrivate::addDatabase(db, connectionName);
    return db;
}

void QSqlDatabasePrivate::addDatabase(const QSqlDatabase &db, const QString &name)
{
    QConnectionDict *dict = dbDict();
    Q_ASSERT(dict);
    QWriteLocker locker(&dict->lock);

    if (dict->contains(name)) {
        invalidateDb(dict->take(name), name);
        qWarning("QSqlDatabasePrivate::addDatabase: duplicate connection name '%s', old "
                 "connection removed.", name.toLocal8Bit().data());
    }
    dict->insert(name, db);
    db.d->connName = name;
}

获取数据库连接

根据连接名获取之前创建的数据库连接,默认打开数据库连接。还可以看到里面有判断之前创建的数据库实例的线程是否为当前线程,如果不是,就返回了空的数据库实例,也就是说创建的数据库实例只能在本线程内使用。

我在网上的博客 

https://www.cnblogs.com/findumars/p/5634462.html

 看到说

“一个线程创建的数据库对象(如 addDatabase 的返回值)只能在同一线程使用,但是,addDatabase 注册的连接(名字是开发者定)可以跨线程使用,唯一需要注意的是,在调用全局方法的时候,要有原子保护。”

 我理解的意思是可以在其他线程中通过连接名获取此连接,也就是使用database(),但是源码也看到了,连接名是跟addDatabase返回的db(数据库对象)成对存在连接池中的,所以就不存在“连接本身用名字可以多线程使用”。

所以,在多线程中使用数据库时候应该保持每个线程都使用一次addDatabase创建连接,创建后,可在当前线程中使用database(connectionName)获取连接,使用数据库。

QSqlDatabase QSqlDatabase::database(const QString& connectionName, bool open)
{
    return QSqlDatabasePrivate::database(connectionName, open);
}

QSqlDatabase QSqlDatabasePrivate::database(const QString& name, bool open)
{
    const QConnectionDict *dict = dbDict();
    Q_ASSERT(dict);

    dict->lock.lo
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值