Qt版本:4.8
百度脑图地址:http://naotu.baidu.com/viewshare.html?shareId=ax1dsrapqk8w
数据库相关应用的基本结构:
表 —— 数据model —— 数据库
从上面图中可以看到Qt提供了三个sql相关的model:QSqlQueryModel、QSqlTableModel、QSqlRelationalModel。
QSqlQueryModel、QSqlTableModel、QSqlRelationalModel三者的比较
1.QSqlQueryModel
该类为SQL结果集提供只读model,比较自由、灵活。使用sql语句完成对数据库的查询。
读写model需要自己写子类,继承QSqlQueryModel,并重写函数:setData()、flags();
2.QSqlTableModel
该类为一个数据库表提供可编辑model,将常用数据库操作都封装成了函数,简单易用。
该类可以设置编辑策略,即用户对model进行的修改,什么时候应用于数据库:
OnFieldChanged 对model的修改立即应用于数据库
OnRowChanged 用户选中新行时,修改应用于数据库(default)
OnManualSubmit 修改缓存于model中,直至调用submitAll()或revertAll()函数。
注意第三种编辑策略,相当于记事本中的保存功能,细想这种策略和事务操作不谋而合,可以将缓存的一系列操作看作是一个事务,代码如下
QSqlTableModel *model = new QSqlTableModel(); model->database().transaction(); //开始事务 if(model->submitAll()) //缓存的操作成功提交 { model->database().commit(); //提交事务 } else { model->database().rollback(); //回滚事务 qDebug() << model->lastError().text(); } model->revertAll(); //撤销所有待定修改
缺点:只能对数据库进行简单增、删、改、查操作。一个model只对应一个数据库表。
3.QSqlRelationalModel
该类为单一数据表提供带有外键支持的可编辑数据模型。相当于在QSqlTableModel基础上对定义外键的Sql语句进行了封装。
附:以QSqlQueryModel为基类,自定义可写model代码片段(帮助文档中的代码)
Qt::ItemFlags EditableSqlModel::flags( const QModelIndex &index) const { Qt::ItemFlags flags = QSqlQueryModel::flags(index); if (index.column() == 1 || index.column() == 2) flags |= Qt::ItemIsEditable; return flags; } bool EditableSqlModel::setData(const QModelIndex &index, const QVariant &value, int /* role */) { if (index.column() < 1 || index.column() > 2) return false; QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0); int id = data(primaryKeyIndex).toInt(); clear(); bool ok; if (index.column() == 1) { ok = setFirstName(id, value.toString()); } else { ok = setLastName(id, value.toString()); } refresh(); return ok; } void EditableSqlModel::refresh() { setQuery("select * from person"); setHeaderData(0, Qt::Horizontal, QObject::tr("ID")); setHeaderData(1, Qt::Horizontal, QObject::tr("First name")); setHeaderData(2, Qt::Horizontal, QObject::tr("Last name")); } bool EditableSqlModel::setFirstName(int personId, const QString &firstName) { QSqlQuery query; query.prepare("update person set firstname = ? where id = ?"); query.addBindValue(firstName); query.addBindValue(personId); return query.exec(); } bool EditableSqlModel::setLastName(int personId, const QString &lastName) { QSqlQuery query; query.prepare("update person set lastname = ? where id = ?"); query.addBindValue(lastName); query.addBindValue(personId); return query.exec(); }