QtSQL学习笔记(4)- 使用SQL Model类
除了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类的更多相关文章
- java学习笔记37(sql工具类:JDBCUtils)
在之前的内容中,我们发现,当我们执行一条语句时,每新建一个方法,就要重新连接一次数据库,代码重复率很高,那么能不能把这些重复代码封装成一个类呢,我们学习方法时,就学习到方法就是为了提高代码的利用率,所 ...
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL 如果使用JDBC或者其他框架,很多时候需要你根据需求手动拼装SQL语句,这是一件非常麻烦的事情.MyBatis提供了对SQL语句动态的组装能力,而且他只有 ...
- Kotlin学习笔记(9)- 数据类
系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正.如果你觉得我的文章对你有用,欢迎关注我,我们一起学习进步! Kotlin学习笔记(1)- 环境配置 Kotlin学习笔记(2)- 空安 ...
- 转:学习笔记: Delphi之线程类TThread
学习笔记: Delphi之线程类TThread - 5207 - 博客园http://www.cnblogs.com/5207/p/4426074.html 新的公司接手的第一份工作就是一个多线程计算 ...
- SQL反模式学习笔记18 减少SQL查询数据,避免使用一条SQL语句解决复杂问题
目标:减少SQL查询数据,避免使用一条SQL语句解决复杂问题 反模式:视图使用一步操作,单个SQL语句解决复杂问题 使用一个查询来获得所有结果的最常见后果就是产生了一个笛卡尔积.导致查询性能降低. 如 ...
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL
- JavaSE学习笔记(14)---File类和IO流(字节流和字符流)
JavaSE学习笔记(14)---File类和IO流(字节流和字符流) File类 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 构造方 ...
- JavaSE学习笔记(8)---常用类
JavaSE学习笔记(8)---常用类 1.Object类 java.lang.Object类是Java语言中的根类,即所有类的父类.它中描述的所有方法子类都可以使用.在对象实例化的时候,最终找的父类 ...
- COCOS2D-X学习笔记(一)-----Node类的学习
Node类(在3.0版本以下叫CCNode):节点类. 本文记录以下几个方法的学习笔记: init()和onEnter()这俩个方法都是CCNode的方法.其区别如下: 1.其被调用的顺序是先init ...
- QtSQL学习笔记(1)- 概述
Qt SQL是Qt提供的核心模块,用以支持SQL数据库.Qt SQL的API被分为不同的层: ■ 驱动层 (Driver layer) ■ API层 (SQL API layer) ■ 用户接口层 ( ...
随机推荐
- 从零开始学android开发-四大组件之一 Activity
1.Activity是Android四大组件(Application Components)之一,简单来说Activity就是平常所见到的用户界面,一般情况下,一个Activity所占的窗口是满屏的, ...
- 获取windows版本信息
procedure TForm1.Button1Click(Sender: TObject); Var OSVI:OSVERSIONINFO; begin OSVI.dwOSversi ...
- 将项目添加到Finder侧边栏和工具栏
转: http://www.cnblogs.com/wormday/archive/2011/05/08/2039468.html 1.在侧边栏和工具栏右键,有相应的设置选项 2.可以将项目拖到侧边栏 ...
- Java基础知识强化之网络编程笔记15:Android网络通信之 Android异步任务处理(AsyncTask使用)
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的 ...
- Java基础知识强化之多线程笔记03:进程与线程 和 多线程的意义
1. 要想了解多线程,必须先了解线程,而要想了解线程,必须先了解进程,因为线程是依赖于进程而存在. 2. 什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,我们发现只有运行的程序才会出 ...
- JS实现字符串去重,数组去重
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Android_ViewFlipper
xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...
- eclipse在线安装svn插件
原文地址:http://www.cnblogs.com/xdp-gacl/p/4354199.html Eclipse在线安装SVN 一.SVN在线安装 下面为在线安装SVN插件.以下是在线安装步骤: ...
- LVM的添加与删除
#############################创建 fdisk -l查看分区情况 fdisk /dev/xvdb pvcreate /dev/xvdb1 vgextend VolGroup ...
- Thinkphp 使用gmail发送邮件
1.Thinkphp 发送邮件内容来自:http://www.thinkphp.cn/code/32.html /** * 系统邮件发送函数 * @param string $to 接收邮件者邮箱 * ...