除了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. AD新建用户、组、OU

    #新建用户 import-csv d:\AD\Users.csv | Foreach {New-ADUser -Name $_.Name -Path $_.Path -samAccountName $ ...

  2. uva 11246 - K-Multiple Free set(数论)

    题目链接:uva 11246 - K-Multiple Free set 题目大意:给定n,k.求一个元素不大于n的子集,要求该子集的元素尽量多,而且不含两个数满足a∗k=b. 解题思路:容斥原理.f ...

  3. 【转】rvm安装ruby,gem,rails,之后仍然无法找到rails命令

    转自:http://chinacheng.iteye.com/blog/1738036 rvm安装ruby和rails之后,ruby -v好使,gem -v好使.但是rails -v不好使,提示没有安 ...

  4. Access-数据类型与.net OleDbType枚举类型对应关系

    列表最常见的数据类型映射 访问类型名称 数据库数据类型 OLEDB 类型 .NET 框架类型 成员名称 文本 VarWChar DBTYPE _ WSTR System.String OleDbTyp ...

  5. wcf-2

    1.前言 上一篇,我 们通过VS自带的模板引擎自动生成了一个wcf程序,接下来我们将手动实现一个wcf程序.由于应用程序开发中一般都会涉及到大量的增删改查业务,所以这 个程序将简单演示如何在wcf中构 ...

  6. Basic Example of JMX Technology--转载

    原文地址:http://nick-lab.gs.washington.edu/java/jdk1.5b/guide/jmx/tutorial/connectors.html Basic Example ...

  7. 数据库通用Jdbc操作

    public class JdbcUtil { /** * 关闭一个数据库链接 * @param conn */ public static void closeConnection(Connecti ...

  8. 优化sql,返回行数少情况下,NL比hash快好多

    sql如下 select t.id, t.value, tt.sort as sortno from ENGINEERING_TYPE t left join ENGINEERING_TYPE tt ...

  9. web项目设计与开发——DBHelper3

    本次学习的内容为根据DBHelper对数据库里的数据进行增删改查 具体内容为: 一.编写程序 1.创建工程——Mangage    2.在src目录下创建五个包,分别为DAO,DBHelper,Ent ...

  10. epoll讲解--转自”知乎“

    http://my.oschina.net/dclink/blog/287198 首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象. 不管是文件,还是套 ...