失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Qt sqlite 使用备忘

Qt sqlite 使用备忘

时间:2020-03-16 18:48:52

相关推荐

Qt sqlite 使用备忘

一. 创建数据库连接

同一数据库,在一个线程中,如果创建多个连接,只有一个连接是打开的(虽然一般也不会这样干)QSqlDatabase类型的对象,只能在创建线程中使用。多线程 访问同一数据库需要创建不同连接(可以在连接名称中加入线程标识,用表记录下各个线程对应的连接,方便下次查询)。

二. QSqlTableModel(写入速度、增删改)

写入速度问题:在操作过程中,如果QSqlTableModel类型对象,一次性进行插入大量数据到模板(或者提交大量修改到数据库),仅使用默认设置会出现长时间的卡顿现象,可通过以下设置进行改善: 将editStrategy设置为OnManualSubmit(手动提交修改)插入数据时不要使用insertRow,而是同直接通过insertRows()批量插入数据

a. 如果需要对插入的数据进行初始化动作,可以通过监控primeInsert()来实现,每次有新的行数据加入 的时候都会发出该信号

b. insertRows添加的数据无法通过submit提交到数据库应用修改到数据库时,各方法的调用顺序设置为:QSqlDatabase::transaction(),QSqlTableModel::submitAll(),QSqlDatabase::commit()。开启事务是为了让数据库的修改动作批量地执行,同时也可以保护数据库的完整性。 关于修改:创建表时,需要设置PRIMARY KEY,否则会出现多行数据都被修改的情况关于插入:调用insertRow/insertRows插入行数据后,还需要对新插入的对象进行赋值操作,submit时,才会真正添加到数据库中关于删除:在OnManualSubmit模式下,删除新增并且未写入数据库的行数据,会立即执行,model中对应的行数据会被删除,可从图形界面(view)观察到。但是,若是删除数据库中已有的行数据,则仅删除命令写入到缓存,只有submitAll,数据库更新之后,才可从图形界面观察到。如果想要在第二种删除动作后,可立即在图形界面看到,但是又不想修改数据库,则除了调用QSqlTableModel本身的removeRow/removeRows外,还要自行处理model的数据(通过调用beginRemoveRows/

endRemoveRows删除model中的行数据。并且要做好行号记录,以免与QSqlTableModel缓存中记录的操作有出入)信息补充

SQLite Transaction

SQLite Transaction中文

QSqlTableModel Class

截取的Transaction部分介绍

截取的insertRows , primeInsert 介绍

QSqlTableModel::removeRows源码

/*!Removes \a count rows starting at \a row. Since this modeldoes not support hierarchical structures, \a parent must bean invalid model index.When the edit strategy is OnManualSubmit, deletion of rows fromthe database is delayed until submitAll() is called.For OnFieldChange and OnRowChange, only one row may be deletedat a time and only if no other row has a cached change. Deletionsare submitted immediately to the database. The model retains ablank row for successfully deleted row until refreshed with select().After failed deletion, the operation is not reverted in the model.The application may resubmit or revert.Inserted but not yet successfully submitted rows in the range to beremoved are immediately removed from the model.Before a row is deleted from the database, the beforeDelete()signal is emitted.If row < 0 or row + count > rowCount(), no action is taken andfalse is returned. Returns \c true if all rows could be removed;otherwise returns \c false. Detailed database error informationcan be retrieved using lastError().\sa removeColumns(), insertRows()*/bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent){Q_D(QSqlTableModel);if (parent.isValid() || row < 0 || count <= 0)return false;else if (row + count > rowCount())return false;else if (!count)return true;if (d->strategy != OnManualSubmit)if (count > 1 || (d->cache.value(row).submitted() && isDirty()))return false;// Iterate backwards so we don't have to worry about removed rows causing// higher cache entries to shift downwards.for (int idx = row + count - 1; idx >= row; --idx) {QSqlTableModelPrivate::ModifiedRow& mrow = d->cache[idx];if (mrow.op() == QSqlTableModelPrivate::Insert) {revertRow(idx);//!!!!!!删除新增并且未写入数据库的行数据,直接回滚,并发出beginRemoveRows信号} else {//!!!!!!!!!删除数据库中已有的行数据,则仅将删除命令写入到缓存,不执行model数据的删除动作if (mrow.op() == QSqlTableModelPrivate::None)mrow = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Delete,QSqlQueryModel::record(idx));elsemrow.setOp(QSqlTableModelPrivate::Delete);if (d->strategy == OnManualSubmit)emit headerDataChanged(Qt::Vertical, idx, idx);}}if (d->strategy != OnManualSubmit)return submit();return true;}void QSqlTableModelPrivate::revertCachedRow(int row){Q_Q(QSqlTableModel);ModifiedRow r = cache.value(row);switch (r.op()) {case QSqlTableModelPrivate::None:Q_ASSERT_X(false, "QSqlTableModelPrivate::revertCachedRow()", "Invalid entry in cache map");return;case QSqlTableModelPrivate::Update:case QSqlTableModelPrivate::Delete:if (!r.submitted()) {cache[row].revert();emit q->dataChanged(q->createIndex(row, 0),q->createIndex(row, q->columnCount() - 1));}break;case QSqlTableModelPrivate::Insert: {QMap<int, QSqlTableModelPrivate::ModifiedRow>::Iterator it = cache.find(row);if (it == cache.end())return;q->beginRemoveRows(QModelIndex(), row, row);it = cache.erase(it);while (it != cache.end()) {int oldKey = it.key();const QSqlTableModelPrivate::ModifiedRow oldValue = it.value();cache.erase(it);it = cache.insert(oldKey - 1, oldValue);++it;}q->endRemoveRows();break; }}}

如果觉得《Qt sqlite 使用备忘》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。