Qt 学习之路 2(56):使用模型操作数据库 (okgogo: skip)

前一章我们使用 SQL 语句完成了对数据库的常规操作,包括简单的 CREATE、SELECT 等语句的使用。我们也提到过,Qt 不仅提供了这种使用 SQL 语句的方式,还提供了一种基于模型的更高级的处理方式。这种基于QSqlTableModel 的模型处理更为高级,如果对 SQL 语句不熟悉,并且不需要很多复杂的查询,这种QSqlTableModel模型基本可以满足一般的需求。本章我们将介绍QSqlTableModel的一般使用,对比 SQL 语句完成对数据库的增删改查等的操作。值得注意的是,QSqlTableModel并不一定非得结合 QListViewQTableView使用,我们完全可以用其作一般性处理。

首先我们来看看如何使用QSqlTableModel 进行 SELECT 操作:

 
if (connect("demo.db")) {
QSqlTableModel model;
model.setTable("student");
model.setFilter("age > 20 and age < 25");
if (model.select()) {
for (int i = 0; i < model.rowCount(); ++i) {
QSqlRecord record = model.record(i);
QString name = record.value("name").toString();
int age = record.value("age").toInt();
qDebug() << name << ": " << age;
}
}
} else {
return 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (connect("demo.db")) {
    QSqlTableModel model;
    model.setTable("student");
    model.setFilter("age > 20 and age < 25");
    if (model.select()) {
        for (int i = 0; i < model.rowCount(); ++i) {
            QSqlRecord record = model.record(i);
            QString name = record.value("name").toString();
            int age = record.value("age").toInt();
            qDebug() << name << ": " << age;
        }
    }
} else {
    return 1;
}

我们依旧使用了前一章的connect()函数。接下来我们创建了QSqlTableModel实例,使用setTable()函数设置所需要操作的表格;setFilter()函数则是添加过滤器,也就是 WHERE 语句所需要的部分。例如上面代码中的操作实际相当于 SQL 语句

PgSQL
SELECT * FROM student WHERE age > 20 and age < 25
1
SELECT * FROM student WHERE age > 20 and age < 25

使用QSqlTableModel::select()函数进行操作,也就是执行了查询操作。如果查询成功,函数返回 true,由此判断是否发生了错误。如果没有错误,我们使用record()函数取出一行记录,该记录是以QSqlRecord的形式给出的,而QSqlRecord::value()则取出一个列的实际数据值。注意,由于QSqlTableModel没有提供const_iterator遍历器,因此不能使用foreach宏进行遍历。

另外需要注意,由于QSqlTableModel只是一种高级操作,肯定没有实际 SQL 语句方便。具体来说,我们使用QSqlTableModel只能进行 SELECT * 的查询,不能只查询其中某些列的数据。

下面一段代码则显示了如何使用QSqlTableModel进行插入操作:

 
QSqlTableModel model;
model.setTable("student");
int row = 0;
model.insertRows(row, 1);
model.setData(model.index(row, 1), "Cheng");
model.setData(model.index(row, 2), 24);
model.submitAll();
1
2
3
4
5
6
7
QSqlTableModel model;
model.setTable("student");
int row = 0;
model.insertRows(row, 1);
model.setData(model.index(row, 1), "Cheng");
model.setData(model.index(row, 2), 24);
model.submitAll();

插入也很简单:model.insertRows(row, 1);说明我们想在索引 0 的位置插入 1 行新的数据。使用setData()函数则开始准备实际需要插入的数据。注意这里我们向 row 的第一个位置写入 Cheng(通过model.index(row, 1),回忆一下,我们把 model 当作一个二维表,这个坐标相当于第 row 行第 1 列),其余以此类推。最后,调用submitAll()函数提交所有修改。这里执行的操作可以用如下 SQL 表示:

PgSQL
INSERT INTO student (name, age) VALUES ('Cheng', 24)
1
INSERT INTO student (name, age) VALUES ('Cheng', 24)

当我们取出了已经存在的数据后,对其进行修改,然后重新写入数据库,即完成了一次更新操作:

 
QSqlTableModel model;
model.setTable("student");
model.setFilter("age = 25");
if (model.select()) {
if (model.rowCount() == 1) {
QSqlRecord record = model.record(0);
record.setValue("age", 26);
model.setRecord(0, record);
model.submitAll();
}
}
1
2
3
4
5
6
7
8
9
10
11
QSqlTableModel model;
model.setTable("student");
model.setFilter("age = 25");
if (model.select()) {
    if (model.rowCount() == 1) {
        QSqlRecord record = model.record(0);
        record.setValue("age", 26);
        model.setRecord(0, record);
        model.submitAll();
    }
}

这段代码中,我们首先找到 age = 25 的记录,然后将 age 重新设置为 26,存入相同的位置(在这里都是索引 0 的位置),提交之后完成一次更新。当然,我们也可以类似其它模型一样的设置方式:setData()函数。具体代码片段如下:

 
if (model.select()) {
if (model.rowCount() == 1) {
model.setData(model.index(0, 2), 26);
model.submitAll();
}
}
1
2
3
4
5
6
if (model.select()) {
    if (model.rowCount() == 1) {
        model.setData(model.index(0, 2), 26);
        model.submitAll();
    }
}

注意我们的 age 列是第 3 列,索引值为 2,因为前面还有 id 和 name 两列。这里的更新操作则可以用如下 SQL 表示:

PgSQL
UPDATE student SET age = 26 WHERE age = 25
1
UPDATE student SET age = 26 WHERE age = 25

删除操作同更新类似:

 
QSqlTableModel model;
model.setTable("student");
model.setFilter("age = 25");
if (model.select()) {
if (model.rowCount() == 1) {
model.removeRows(0, 1);
model.submitAll();
}
}
1
2
3
4
5
6
7
8
9
QSqlTableModel model;
model.setTable("student");
model.setFilter("age = 25");
if (model.select()) {
    if (model.rowCount() == 1) {
        model.removeRows(0, 1);
        model.submitAll();
    }
}

如果使用 SQL 则是:

PgSQL
DELETE FROM student WHERE age = 25
1
DELETE FROM student WHERE age = 25

当我们看到removeRows()函数就应该想到:我们可以一次删除多行。事实也正是如此,这里不再赘述。

Qt 学习之路 2(56):使用模型操作数据库的更多相关文章

  1. FastAPI 学习之路(三十三)操作数据库

    通过创建pydantic模型进行验证提交数据 from pydantic import BaseModel class UserBase(BaseModel): email: str class Us ...

  2. Qt 学习之路 2(55):数据库操作

    Qt 提供了 QtSql 模块来提供平台独立的基于 SQL 的数据库操作.这里我们所说的“平台独立”,既包括操作系统平台,又包括各个数据库平台.另外,我们强调了“基于 SQL”,因为 NoSQL 数据 ...

  3. Qt 学习之路 2(51):布尔表达式树模型

    Qt 学习之路 2(51):布尔表达式树模型 豆子 2013年5月15日 Qt 学习之路 2 17条评论 本章将会是自定义模型的最后一部分.原本打算结束这部分内容,不过实在不忍心放弃这个示例.来自于 ...

  4. Qt 学习之路 2(50):自定义可编辑模型

    Home / Qt 学习之路 2 / Qt 学习之路 2(50):自定义可编辑模型 Qt 学习之路 2(50):自定义可编辑模型 豆子 2013年5月13日 Qt 学习之路 2 13条评论 上一章我们 ...

  5. Qt 学习之路 2(49):自定义只读模型

    Qt 学习之路 2(49):自定义只读模型 豆子 2013年5月5日 Qt 学习之路 2 18条评论 model/view 模型将数据与视图分割开来,也就是说,我们可以为不同的视图,QListView ...

  6. Qt 学习之路 2(45):模型

    Home / Qt 学习之路 2 / Qt 学习之路 2(45):模型 Qt 学习之路 2(45):模型  豆子  2013年2月26日  Qt 学习之路 2  23条评论 在前面两章的基础之上,我们 ...

  7. Qt 学习之路 2(67):访问网络(3)

    Qt 学习之路 2(67):访问网络(3) 豆子 2013年11月5日 Qt 学习之路 2 16条评论 上一章我们了解了如何使用我们设计的NetWorker类实现我们所需要的网络操作.本章我们将继续完 ...

  8. Qt 学习之路 2(66):访问网络(2)

    Home / Qt 学习之路 2 / Qt 学习之路 2(66):访问网络(2) Qt 学习之路 2(66):访问网络(2)  豆子  2013年10月31日  Qt 学习之路 2  27条评论 上一 ...

  9. Qt 学习之路 2(59):使用流处理 XML

    Qt 学习之路 2(59):使用流处理 XML 豆子 2013年7月25日 Qt 学习之路 2 18条评论 本章开始我们将了解到如何使用 Qt 处理 XML 格式的文档. XML(eXtensible ...

随机推荐

  1. android 拍照+拍照button 以及返回按钮布局

    公司最近做一个项目拍照总是崩溃,所以决定自己写一个拍照的方法,在网上调研一番,写了一个简单demo,现共享如下 主要CameraActivity CameraActivity package com. ...

  2. dokuwiki安装问题

    工作了几年,虽然在程序员这个道路上才算开始,希望以后能够有所成长,为了把平时遇到的技术问题,记录下来,第一个想到的就是写wiki,博客虽然创建了许久,但是没有坚持写下去,在网上找了许多的wiki程序, ...

  3. 当一个SQL语句同时出现了where,group by,having,order by的时候,执行顺序和编写顺序

    当一个查询语句同时出现了where,group by,having,order by的时候,执行顺序和编写顺序 1.执行where xx对全表数据做筛选,返回第1个结果集. 2.针对第1个结果集使用g ...

  4. VMware设置及linux静态ip设置

    1.   VMWARE虚拟机NAT模式上网设置 1.1. VM虚拟机设置 1.1.1.   虚拟机全局设置 启动虚拟机选择[虚拟网络编辑器] 如果需要管理员权限点[更改设置],没有提示这忽略这一步 选 ...

  5. NanoPi2

    https://item.taobao.com/item.htm?spm=a230r.1.14.9.Ijhc8S&id=526981593477&ns=1&abbucket=1 ...

  6. c# 获取非托管指针长度

    public List<string> GetPDFValues() { List<string> strs = new List<string>(); unsaf ...

  7. css总结5:px、em、rem区别介绍

    1 PX px像素(Pixel).相对长度单位.像素px是相对于显示器屏幕分辨率而言的. PX特点 1. 浏览器无法调整px单位的字体,以em或rem为字体单位可调整字体. 2 EM em是相对长度单 ...

  8. madvise、fadvise、posix_madvise和posix_fadvise函数的使用

    系统调用madvise的作用:建议内核如何使用指定段的内存.函数原型如下: #include <sys/mman.h> int madvise(void *addr, size_t len ...

  9. 学习React中遇到的问题

    1.执行eject后,再次启动项目报错 情景:使用create-react-app搭建了项目,启动没有问题,然后执行 $ yarn eject 暴露出webpack配置文件等,再次 $ yarn st ...

  10. Sql Server 日期格式化函數 Convert

    Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2015 10:57AM Select CONVERT(varchar(100), GETDATE( ...