除了QSqlQuery,Qt提供了3个高级类用于访问数据库。这些类是QSqlQueryModel、QSqlTableModel和QSqlRelationalTableModel。

这些类是由QAbstractTableModel(继承自QAbstractItemModel)驱动并且它通过一个条目视图类(比如QListView和QTableView)使得表示数据库的数据更加简单。这个详细介绍在“用一个表视图表示数据”一节。

使用这些类的另外一个好处是它使得你的代码能够更容易适用于其他数据源。例如,如果你使用的是QSqlTableModel,之后你打算使用XML文件来替换数据库存储数据,那么这个仅仅是简单地用一个数据模型替换另一个数据模型的问题。

SQL查询模型

QSqlQueryModel提供一个基于SQL查询的只读模型。例如:

 QSqlQueryModel model;
model.setQuery("SELECT * FROM employee"); for (int i = ; i < model.rowCount(); ++i) {
int id = model.record(i).value("id").toInt();
QString name = model.record(i).value("name").toString();
qDebug() << id << name;
}

在使用QSqlQueryModel::setQuery()设置好查询之后,你可以使用QSqlQueryModel::record(int)来访问单个记录。你也可以使用QSqlQueryModel::data()和其他任何继承自QAbstractItemModel的函数。

还有一个重载的setQuery()方法,它带有一个QSqlQuery对象并且在它的结果集中进行操作。它使得你可以使用QSqlQuery的任意特性来设置查询(例如,prepared queries)。

SQL表模型

QSqlTableModel提供一个一次只能对一个SQL表进行操作的可读可写模型。例如:

 QSqlTableModel model;
model.setTable("employee");
model.setFilter("salary > 50000");
model.setSort(, Qt::DescendingOrder);
model.select(); for (int i = ; i < model.rowCount(); ++i) {
QString name = model.record(i).value("name").toString();
int salary = model.record(i).value("salary").toInt();
qDebug() << name << salary;
}

QSqlTableModel是一个高级的可替代QSqlQuery的模型,可以用于浏览和修改单个SQL表。它典型的优点是只需要少量的代码并且不需要了解SQL语法。

使用QSqlTableModel::record()来检索表中的一行,然后使用QSqlTableModel::setRecord()来修改这一行。例如,下面的代码将对所有雇员的薪水增加10%。

 for (int i = ; i < model.rowCount(); ++i) {
QSqlRecord record = model.record(i);
double salary = record.value("salary").toInt();
salary *= 1.1;
record.setValue("salary", salary);
model.setRecord(i, record);
}
model.submitAll();

你也可以使用继承自QAbstractItemModel的方法QSqlTableModel::data()和QSqlTableModel::setData()来修改这些数据。例如,下面的代码展示了怎样用setData()更新一条记录:

 model.setData(model.index(row, column), );
model.submitAll();

下面的代码时怎样插入一行:

 model.insertRows(row, );
model.setData(model.index(row, ), );
model.setData(model.index(row, ), "Peter Gordon");
model.setData(model.index(row, ), );
model.submitAll();

下面的代码时如何删除5条连续行:

 model.removeRows(row, );
model.submitAll();

QSqlTableModel::removeRows()的第一个参数是带删除的第一行的索引号。

当你完成了对记录的修改,你总是需要调用QSqlTableModel::submitAll()来确保这些改动被写入到数据库中。

什么时候以及是否真的需要调用submitAll()实际上取决于表的编辑策略(edit strategy),默认的策略是QSqlTableModel::OnRowChange,也就是说当用户选择了另一个不同的行时上一行的改动将被应用到数据库。其他的策略还包括QSqlTableModel::OnManualSubmit(所有改动将缓存在模型中,直到你调用submitAll()方法)和QSqlTableModel::OnFieldChange (不缓存改动)。这些策略在QSqlTableModel结合一个视图一起使用时相当有用。

SQL关系表模型

QSqlRelationalTableModel扩展了QSqlTableModel来提供了对外键(foreign key)的支持。一个外键是一个表中的一个字段与另一个表中的主键(primary key)字段之间的一一映射。例如,如果一个book表中有一个authorid字段关联到author表中的id字段,那么我们说authorid是一个外键。

The screenshot on the left shows a plain QSqlTableModel in a QTableView. Foreign keys (city and country) aren't resolved to human-readable values. The screenshot on the right shows a QSqlRelationalTableModel, with foreign keys resolved into human-readable text strings.

下面的代码片段展示了如何设置QSqlRelationalTableModel:

 model->setTable("employee");

 model->setRelation(, QSqlRelation("city", "id", "name"));
model->setRelation(, QSqlRelation("country", "id", "name"));

可以查阅QSqlRelationalTableModel文档了解更多内容。

QtSQL学习笔记(4)- 使用SQL Model类的更多相关文章

  1. java学习笔记37(sql工具类:JDBCUtils)

    在之前的内容中,我们发现,当我们执行一条语句时,每新建一个方法,就要重新连接一次数据库,代码重复率很高,那么能不能把这些重复代码封装成一个类呢,我们学习方法时,就学习到方法就是为了提高代码的利用率,所 ...

  2. MyBatis:学习笔记(4)——动态SQL

    MyBatis:学习笔记(4)——动态SQL 如果使用JDBC或者其他框架,很多时候需要你根据需求手动拼装SQL语句,这是一件非常麻烦的事情.MyBatis提供了对SQL语句动态的组装能力,而且他只有 ...

  3. Kotlin学习笔记(9)- 数据类

    系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正.如果你觉得我的文章对你有用,欢迎关注我,我们一起学习进步! Kotlin学习笔记(1)- 环境配置 Kotlin学习笔记(2)- 空安 ...

  4. 转:学习笔记: Delphi之线程类TThread

    学习笔记: Delphi之线程类TThread - 5207 - 博客园http://www.cnblogs.com/5207/p/4426074.html 新的公司接手的第一份工作就是一个多线程计算 ...

  5. SQL反模式学习笔记18 减少SQL查询数据,避免使用一条SQL语句解决复杂问题

    目标:减少SQL查询数据,避免使用一条SQL语句解决复杂问题 反模式:视图使用一步操作,单个SQL语句解决复杂问题 使用一个查询来获得所有结果的最常见后果就是产生了一个笛卡尔积.导致查询性能降低. 如 ...

  6. MyBatis:学习笔记(4)——动态SQL

    MyBatis:学习笔记(4)——动态SQL

  7. JavaSE学习笔记(14)---File类和IO流(字节流和字符流)

    JavaSE学习笔记(14)---File类和IO流(字节流和字符流) File类 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 构造方 ...

  8. JavaSE学习笔记(8)---常用类

    JavaSE学习笔记(8)---常用类 1.Object类 java.lang.Object类是Java语言中的根类,即所有类的父类.它中描述的所有方法子类都可以使用.在对象实例化的时候,最终找的父类 ...

  9. COCOS2D-X学习笔记(一)-----Node类的学习

    Node类(在3.0版本以下叫CCNode):节点类. 本文记录以下几个方法的学习笔记: init()和onEnter()这俩个方法都是CCNode的方法.其区别如下: 1.其被调用的顺序是先init ...

  10. QtSQL学习笔记(1)- 概述

    Qt SQL是Qt提供的核心模块,用以支持SQL数据库.Qt SQL的API被分为不同的层: ■ 驱动层 (Driver layer) ■ API层 (SQL API layer) ■ 用户接口层 ( ...

随机推荐

  1. WINAPI 变量(2861个)

    WINAPI 变量(2861个)   这是从 c:\Program Files\Windows Kits\8.1\Include\um\WinUser.h 这个文件 中提取的 CTRL+F 查看变量所 ...

  2. 【ALearning】第三章 Android基本常见控件

    本章主要介绍主要的寻常较多使用的控件,包含TextView.EditView.ImageView.Button等.本章将介绍相关控件基本属性的使用,为以后章节的进阶学习提供基础.案例中引用的Linea ...

  3. html页面docutype前面出现字符会导致IE678 margin:0 auto;失效

    html页面<!DOCTYPE html>前面出现字符会导致IE678 margin:0 auto;失效

  4. sql根据表名获取字段及对应说明

    SELECT TableName = OBJECT_NAME(c.object_id), ColumnsName = c.name, Description = ex.value, ColumnTyp ...

  5. How to setup SLF4J and LOGBack in a web app - fast--转载

    原文:https://wiki.base22.com/display/btg/How+to+setup+SLF4J+and+LOGBack+in+a+web+app+-+fast Logback is ...

  6. 去掉Eclipse中的Validating

    去掉Eclipse中的Validating 最近我的Eclipse一直经常效验javascript,我疯了校验了一个多小时还是在验.我只能在项目的.project文件中: 去掉.project文件中的 ...

  7. 程序员谈学习:我为什么要学习Linux?

    http://kb.cnblogs.com/page/196876/ 好长时间没好好写点东西了,前段时间由于项目的需要出差了一个多月,期间各种加班,每天晚上加班到十点,回到宾馆实现是没什么精力再写博客 ...

  8. 学习jQuery后的部分总结

    1.remove和empty <div id="div1"> <ul id="ul1"> <li>嘿嘿</li> ...

  9. 一些ecplise 快捷键

    1 F5:下一步,可以进入下一个函数栈 2 F6:当前函数的下一步,不会进入其他的函数. 3 F8:下一个断点. 4 选中一个变量或者表达式,按ctrl+shift+i 来查看内容或者添加监视的方式. ...

  10. MATLAB 误差函数erf(x)

    误差函数: 1.误差函数定义为:   它的性质如下: 2 互补误差函数定义为: 它具有如下性质: 下表给出了误差函数的部分数值: 0.00 0.00000 0.05 0.05637 0.10 0.11 ...