记录QT QSqlDatabase SQLite 多线程使用时报错..
首先QSqlDatabase同一个实例, 不能多线程使用.
如果多线程使用,需要给每个线程创建一个QSqlDatabase实例, 一般是用Map维护各个线程实例链接, key是线程ID, value就是QSqlDatabase指针,例如:
static QMap<Qt::HANDLE,QSqlDatabase*> mapInstance;
Key(Qt::HANDLE)是: QThread::currentThreadId() 返回值, Value是: QSqlDatabase实例指针。
建议写一个全局可以使用的获取QSqlDatabase实例静态方法,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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; //当前线程数据库链接 }; |
1 | <br>为了更方便使用, QSqlDatabase通过DBHelper 封装了一层,添加了query方法。<br>需要注意的点是在通过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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
2019-08-18 miflash刷机出现cannot receive hello packet,和一开始认识9008端口之后不认问题。