Qt多线程与数据库

需求:

数据库的一张表里有10000条数据

一下子都读出来,页面会卡死。

之前上个项目用的方法是分页显示,数据库查询时加limit

这次情景不同,如果就必须要把数据都读出来。

那么可以用多线程,在子线程中查询数据,主线程可以弹出一个模态窗口进行提示,如“数据载入中”。

但是我按这个思路走下去,程序会出现偶发的崩溃。

去找原因时,猜测应该是因为由QSqlDataBase::addDatabase()生成的QSqlDatabase只能在创建它的线程中使用

qt数据库多线程问题的解决(QSqlDatabase只能在创建它的线程中使用)_qsqlite不支持多线程-CSDN博客

解决思路是:

如果希望在子线程中完成对数据库的查询操作,那么在子线程中重新添加一个新的连接名。

比如线程A
QSqlDatabase::addDatabase("QSQLITE", "A");
QSqlQuery query(QSqlDatabase::database("A"));

线程B
QSqlDatabase::addDatabase("QSQLITE", "B");
QSqlQuery query(QSqlDatabase::database("B"));

Qt中,由于多线程并发访问数据库可能导致数据一致性问题和锁竞争,因此需要谨慎处理。当在多线程环境中使用Qt数据库时,可以采用以下策略: 1. **避免直接共享数据库实例**: 每个线程应该有自己的数据库实例,避免在一个线程中修改的数据被其他线程看到。这通常通过Qt的信号槽机制(QObject的signals/slots)或者自定义线程类完成。 ```cpp class WorkerThread : public QThread { public: WorkerThread(DatabaseClass* db) : m_db(db), m_sql("SELECT * FROM table") {} private: void run() override { QSqlQuery query(*m_db); if (query.exec(m_sql)) { // 在这里处理查询结果 } } private: DatabaseClass* m_db; // 线程本地数据库实例 QSqlQuery m_sql; }; ``` 2. **使用信号槽同步**: 当一个线程需要更新数据库时,可以发出一个信号通知主线程或另一个线程已完成,然后由主线程负责调用数据库操作。 ```cpp class MainThread { public: void startQuery(QSqlQuery &sqlQuery) { emit databaseChanged(); QSqlQuery result = dbInstance.exec(sqlQuery); // 线程安全 // 处理结果 } signals: void databaseChanged(); // 发出信号通知数据库已更新 }; // 使用时 databaseThread.start(); // 启动工作线程 connect(&mainThread, &MainThread::databaseChanged, this, &DatabaseClass::handleUpdateSignal); ``` 3. **使用事务管理**: 为了保证数据完整性,可以在数据库操作前开启事务,完成后提交或回滚事务。 4. **使用Qt Concurrency**: 可以使用QFuture或者QThreadPool来异步执行数据库操作,这样可以在后台线程执行数据库请求,主进程继续保持响应能力。 注意:始终遵守数据库最佳实践,如使用预编译的SQL语句,避免长时间锁定表等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lpl还在学习的路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值