找回密码
 立即注册
收起左侧

Qt学习之路第56篇 使用模型操作数据库

2
回复
11954
查看
[复制链接]
累计签到:3 天
连续签到:1 天
来源: 2013-9-10 10:24:36 显示全部楼层 |阅读模式

马上注册,查看详细内容!注册请先查看:注册须知

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
版权声明

该文章原创于Qter开源社区(www.qter.org),作者devbean,博客www.devbean.net,转载请注明出处!


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



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

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

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

  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 进行插入操作:

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

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

  1. INSERT INTO student (name, age) VALUES ('Cheng', 24)
复制代码

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

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

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

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

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

  1. UPDATE student SET age = 26 WHERE age = 25
复制代码

删除操作同更新类似:

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

如果使用 SQL 则是:

  1. DELETE FROM student WHERE age = 25
复制代码

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





回复

使用道具 举报

累计签到:10 天
连续签到:1 天
2014-4-30 16:09:54 显示全部楼层
老师你好,请问可以在tableview里面把数据库的内容自动滚动显示嘛?在网上搜了一下,感觉还是没有什么思路,能不能请老师提供一下思路。。??~~谢谢~~
回复 支持 反对

使用道具 举报

累计签到:7 天
连续签到:1 天
2017-2-17 20:17:11 显示全部楼层
本帖最后由 canid 于 2017-2-17 20:25 编辑

这个用法很奇葩,有点反人类。修改数据之前还要先查询,再来一个submitAll,也不支持链式语法,效率低啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了