社区版本的QSqlDatabase 在多线程下访问是有问题的,需要在不同的线程下调用addDatabase。这样一般会考虑使用一个hash来存储各个QSqlDatabase,并通过和线程ID相关的连接名获取QSqlDatabase。这里提供一个简单版本,使用thread_local变量,在该对象的构造函数中addDatabase并打开该数据库,在析构函数中removeDatabase。代码如下:
#include <QSqlDatabase>
#include <QThread>
class SqlDatabaseHolder
{
public:
QSqlDatabase database_;
static QString connectName()
{
return QString("thread%1").arg((std::size_t)QThread::currentThreadId());
}
SqlDatabaseHolder()
{
database_=QSqlDatabase::addDatabase("QSQLITE",connectName());
database_.setDatabaseName("text.db");
database_.open();
}
~SqlDatabaseHolder()
{
if(database_.isOpen())
{
database_.close();
database_=QSqlDatabase();
}
QSqlDatabase::removeDatabase(connectName());
}
};
thread_local std::unique_ptr<SqlDatabaseHolder> g_database_holder;
QSqlDatabase& getSqlDatabase()
{
if(!g_database_holder)
g_database_holder=std::make_unique<SqlDatabaseHolder>();
return g_database_holder->database_;
}