首先QSqlDatabase同一个实例, 不能多线程使用.
如果多线程使用,需要给每个线程创建一个QSqlDatabase实例, 一般是用Map维护各个线程实例链接, key是线程ID, value就是QSqlDatabase指针,例如:
static QMap<Qt::HANDLE,QSqlDatabase*> mapInstance;
Key(Qt::HANDLE)是: QThread::currentThreadId() 返回值, Value是: QSqlDatabase实例指针。
建议写一个全局可以使用的获取QSqlDatabase实例静态方法,例如:
class DBHelper { public: static DBHelper* GetInstance() { if(!databaseMap.contains(QThread::currentThreadId())) { databaseMap.insert(QThread::currentThreadId(), new DBHelper()); } return databaseMap[QThread::currentThreadId()]; } DBHelper() { //创建数据库链接并指定链接名称 this->database = QSqlDatabase::addDatabase("QSQLITE", QString::number((int)QThread::currentThreadId())); this->database.setDatabaseName("D:/work/svnwork/ProbeTable/probe.db"); this->database.open();//是否打开成功判断 } void query(QString sql) { QSqlQuery sql_query(this->database);//必须指定当前数据库实例 qDebug() << sql_query.exec(sql);//是否执行成功判断 } private: static QMap<Qt::HANDLE, DBHelper*> databaseMap;//所有数据库链接,key: 线程ID, value 数据库链接实例指针 QSqlDatabase database;//当前线程数据库链接 };
为了更方便使用, QSqlDatabase通过DBHelper 封装了一层,添加了query方法。
需要注意的点是在通过QSqlDatabase::addDatabase函数为每个线程创建链接时,需要给每个线程分配一个连接名称:
QSqlDatabase::addDatabase("QSQLITE", QString::number((int)QThread::currentThreadId()));
这里直接用的当前线程ID当的链接名称, 不一定必须是线程ID,只要在全局中是唯一的就可以。
如果没有指定线程名称, 默认走的是QSqlDatabase内部的默认名称,也就是defaultConnection,这是addDatabase函数原型:
static QSqlDatabase addDatabase(QSqlDriver* driver, const QString& connectionName = QLatin1String(defaultConnection));
如果在调用addDatabase的时候没有指定链接名称, 很有可能后创建的QSqlDatabase 链接覆盖掉之前的,。(因为没指定链接名称时,走的都是默认链接名称defaultConnection)。就会在第二次调用addDatabase函数时出现错误:
QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work. QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed. QSqlDatabasePrivate::database: requested database does not belong to the calling thread. QSqlQuery::exec: database not open SQLINFO: QSqlError("", "Driver not loaded", "Driver not loaded")
最后在使用DBHelper前,声明静态变量databaseMap,像这样:
main.cpp:
QMap<Qt::HANDLE, DBHelper*> DBHelper::databaseMap; int main(void){ //... return 0; }
标签:SQLite,QT,database,addDatabase,DBHelper,线程,多线程,QSqlDatabase,链接 From: https://www.cnblogs.com/GengMingYan/p/16597176.html