除了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. MySQL数据库导入外部*.sql文件具体步骤

    如需转载请标明出处:http://blog.csdn.net/itas109 环境: MySQL  50515 Navicat for MySQL 一.导入前提 确保导入的sql文件的host和por ...

  2. MongDB简介

    一.基本概念 MongoDB 是一个高性能,开源,无模式的文档型数据库,是当前NoSQL 数据库产品中最热门的一种.它在许多场景下可用于替代传统的关系型数据库或键/值存储方式,MongoDB 使用C+ ...

  3. 设计模式之Composite模式(笔记)

    组合模式:将对象组合成树形结构以表示"部分-总体"的层次结构. 组合模式使得用户对单个对象和组合对象的使用具有一致性. 适用场合:当需求中是体现部分与总体层次的结构时,以及希望用户 ...

  4. 隐式Intent实例

    注意:The <strong>categories</strong>, if supplied, must <em>all</em> be listed ...

  5. 基于cocos2d-x的游戏框架设计——李成

    视频:http://v.youku.com/v_show/id_XMzc5ODUyMTI4.html?f=17330006 网易科技讯 3月31日,第四届CocoaChina开发者大会暨Cocos2d ...

  6. Android ADB启动失败 ADB server out of date

    调试Android程序时总提示ADB未运行,转到命令行方式下启动ADB, adb kille-server停止ADB, 然后再运行adb start-server 随后提示: adb server i ...

  7. 定位CoreLocation

    一.定位 iOS三种定位方式: CoreLocation 按定位的准确性: GPS(Global Positioning System全球定位系统); 蜂窝式基站; wifi; 定位顺序:1. 首选G ...

  8. Android HTTPS如何10分钟实现自签名SSL证书

    前言 去年公司内一个应用加了支付宝支付功能,为了保证安全,支付请求链接写成了https. 由于公司服务器使用的是的自签名证书,而在Android系统中自己签署的不能通过验证的,所以会抛出错误. 于是我 ...

  9. gdb显示内存命令用法简介

    http://blog.csdn.net/allenlinrui/article/details/5964046

  10. js回调函数callback()

    <a id="btnSave" href="javascript:void(0)" class="easyui-linkbutton" ...