Qt 学习之路 2(58):编辑数据库外键
Qt 学习之路 2(58):编辑数据库外键(skip)
前面几章我们介绍了如何对数据库进行操作以及如何使用图形界面展示数据库数据。本章我们将介绍如何对数据库的数据进行编辑。 当然,我们可以选择直接使用 SQL 语句进行更新,这一点同前面所说的 model/view 的编辑没有什么区别。除此之外,Qt 还为图形界面提供了更方便的展示并编辑的功能。
普通数据的编辑很简单,这里不再赘述。不过,我们通常会遇到多个表之间存在关联的情况。首先我们要提供一个 city 表:
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR);
INSERT INTO city (name) VALUES ('Beijing');
INSERT INTO city (name) VALUES ('Shanghai');
INSERT INTO city (name) VALUES ('Nanjing');
INSERT INTO city (name) VALUES ('Tianjin');
INSERT INTO city (name) VALUES ('Wuhan');
INSERT INTO city (name) VALUES ('Hangzhou');
INSERT INTO city (name) VALUES ('Suzhou');
INSERT INTO city (name) VALUES ('Guangzhou');
|
1
2
3
4
5
6
7
8
9
10
11
12
|
CREATE TABLE city (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR);
INSERT INTO city (name) VALUES ('Beijing');
INSERT INTO city (name) VALUES ('Shanghai');
INSERT INTO city (name) VALUES ('Nanjing');
INSERT INTO city (name) VALUES ('Tianjin');
INSERT INTO city (name) VALUES ('Wuhan');
INSERT INTO city (name) VALUES ('Hangzhou');
INSERT INTO city (name) VALUES ('Suzhou');
INSERT INTO city (name) VALUES ('Guangzhou');
|
由于 city 表是一个参数表,所以我们直接将所需要的城市名称直接插入到表中。接下来我们创建 student 表,并且使用外键连接 city 表:
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR,
age INTEGER,
address INTEGER,
FOREIGN KEY(address) REFERENCES city(id));
|
1
2
3
4
5
6
|
CREATE TABLE student (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR,
age INTEGER,
address INTEGER,
FOREIGN KEY(address) REFERENCES city(id));
|
我们重新创建 student 表(如果你使用的 RDBMS 支持 ALTER TABLE 语句直接修改表结构,就不需要重新创建了;否则的话只能先删除旧的表,再创建新的表,例如 sqlite)。
这里需要注意一点,如果此时我们在 Qt 中直接使用
|
1
|
INSERT INTO student (name, age, address) VALUES ('Tom', 24, 100);
|
语句,尽管我们的 city 中没有 ID 为 100 的记录,但还是是可以成功插入的。这是因为虽然 Qt 中的 sqlite 使用的是支持外键的 sqlite3,但 Qt 将外键屏蔽掉了。为了启用外键,我们需要首先使用QSqlQuery执行:
|
1
|
PRAGMA foreign_keys = ON;
|
然后就会发现这条语句不能成功插入了。接下来我们插入一些正常的数据:
INSERT INTO student (name, age, address) VALUES ('Jack', 23, 1);
INSERT INTO student (name, age, address) VALUES ('Jane', 22, 4);
INSERT INTO student (name, age, address) VALUES ('Jerry', 25, 5);
|
1
2
3
4
|
INSERT INTO student (name, age, address) VALUES ('Tom', 20, 2);
INSERT INTO student (name, age, address) VALUES ('Jack', 23, 1);
INSERT INTO student (name, age, address) VALUES ('Jane', 22, 4);
INSERT INTO student (name, age, address) VALUES ('Jerry', 25, 5);
|
下面,我们使用 model/view 方式来显示数据:
model->setTable("student");
model->setSort(ColumnID_Name, Qt::AscendingOrder);
model->setHeaderData(ColumnID_Name, Qt::Horizontal, "Name");
model->setHeaderData(ColumnID_Age, Qt::Horizontal, "Age");
model->setHeaderData(ColumnID_City, Qt::Horizontal, "City");
model->select();
QTableView *view = new QTableView(this);
view->setModel(model);
view->setSelectionMode(QAbstractItemView::SingleSelection);
view->setSelectionBehavior(QAbstractItemView::SelectRows);
view->resizeColumnsToContents();
QHeaderView *header = view->horizontalHeader();
header->setStretchLastSection(true);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
QSqlTableModel *model = new QSqlTableModel(this);
model->setTable("student");
model->setSort(ColumnID_Name, Qt::AscendingOrder);
model->setHeaderData(ColumnID_Name, Qt::Horizontal, "Name");
model->setHeaderData(ColumnID_Age, Qt::Horizontal, "Age");
model->setHeaderData(ColumnID_City, Qt::Horizontal, "City");
model->select();
QTableView *view = new QTableView(this);
view->setModel(model);
view->setSelectionMode(QAbstractItemView::SingleSelection);
view->setSelectionBehavior(QAbstractItemView::SelectRows);
view->resizeColumnsToContents();
QHeaderView *header = view->horizontalHeader();
header->setStretchLastSection(true);
|
这段代码和我们前面见到的没有什么区别。我们可以将其补充完整后运行一下看看:

注意外键部分:City 一列仅显示出了我们保存的外键。如果我们使用QSqlQuery,这些都不是问题,我们可以将外键信息放在一个 SQL 语句中 SELECT 出来。但是,我们不想使用QSqlQuery,那么现在可以使用另外的一个模型:QSqlRelationalTableModel。QSqlRelationalTableModel与QSqlTableModel十分类似,可以为一个数据库表提供可编辑的数据模型,同时带有外键的支持。下面我们修改一下我们的代码:
model->setTable("student");
model->setSort(ColumnID_Name, Qt::AscendingOrder);
model->setHeaderData(ColumnID_Name, Qt::Horizontal, "Name");
model->setHeaderData(ColumnID_Age, Qt::Horizontal, "Age");
model->setHeaderData(ColumnID_City, Qt::Horizontal, "City");
model->setRelation(ColumnID_City, QSqlRelation("city", "id", "name"));
model->select();
QTableView *view = new QTableView(this);
view->setModel(model);
view->setSelectionMode(QAbstractItemView::SingleSelection);
view->setSelectionBehavior(QAbstractItemView::SelectRows);
view->resizeColumnsToContents();
view->setItemDelegate(new QSqlRelationalDelegate(view));
QHeaderView *header = view->horizontalHeader();
header->setStretchLastSection(true);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this);
model->setTable("student");
model->setSort(ColumnID_Name, Qt::AscendingOrder);
model->setHeaderData(ColumnID_Name, Qt::Horizontal, "Name");
model->setHeaderData(ColumnID_Age, Qt::Horizontal, "Age");
model->setHeaderData(ColumnID_City, Qt::Horizontal, "City");
model->setRelation(ColumnID_City, QSqlRelation("city", "id", "name"));
model->select();
QTableView *view = new QTableView(this);
view->setModel(model);
view->setSelectionMode(QAbstractItemView::SingleSelection);
view->setSelectionBehavior(QAbstractItemView::SelectRows);
view->resizeColumnsToContents();
view->setItemDelegate(new QSqlRelationalDelegate(view));
QHeaderView *header = view->horizontalHeader();
header->setStretchLastSection(true);
|
这段代码同前面的几乎一样。我们首先创建一个QSqlRelationalTableModel对象。注意,这里我们有一个setRelation()函数的调用。该语句说明,我们将第ColumnID_City列作为外键,参照于 city 表的 id 字段,使用 name 进行显示。另外的setItemDelegate()语句则提供了一种用于编辑外键的方式。运行一下程序看看效果:

此时,我们的外键列已经显示为 city 表的 name 字段的实际值。同时在编辑时,系统会自动成为一个QComboBox供我们选择。当然,我们需要自己将选择的外键值保存到实际记录中,这部分我们前面已经有所了解。
Qt 学习之路 2(58):编辑数据库外键的更多相关文章
- 《Qt 学习之路 2》目录
<Qt 学习之路 2>目录 <Qt 学习之路 2>目录 豆子 2012年8月23日 Qt 学习之路 2 177条评论 <Qt 学习之路 2>目录 序 Qt ...
- Qt 学习之路 2(57):可视化显示数据库数据
Qt 学习之路 2(57):可视化显示数据库数据(skip) 豆子 2013年6月26日 Qt 学习之路 2 26条评论 前面我们用了两个章节介绍了 Qt 提供的两种操作数据库的方法.显然,使用QSq ...
- Qt 学习之路 2(56):使用模型操作数据库
Qt 学习之路 2(56):使用模型操作数据库 (okgogo: skip) 豆子 2013年6月20日 Qt 学习之路 2 13条评论 前一章我们使用 SQL 语句完成了对数据库的常规操作,包括简单 ...
- Qt 学习之路 2(50):自定义可编辑模型
Home / Qt 学习之路 2 / Qt 学习之路 2(50):自定义可编辑模型 Qt 学习之路 2(50):自定义可编辑模型 豆子 2013年5月13日 Qt 学习之路 2 13条评论 上一章我们 ...
- Qt 学习之路 2(41):model/view 架构
Qt 学习之路 2(41):model/view 架构 豆子 2013年1月23日 Qt 学习之路 2 50条评论 有时,我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应 ...
- Qt 学习之路 2(8):添加动作
Home / Qt 学习之路 2 / Qt 学习之路 2(8):添加动作 [在WINDOWS10 QTCREATOR MENU添加无效] Qt 学习之路 2(8):添加动作 豆子 ...
- Qt 学习之路 2(6):Qt 模块简介
Home / Qt 学习之路 2 / Qt 学习之路 2(6):Qt 模块简介 豆子 2012年8月26日 Qt 学习之路 2 20条评论 Qt 5 与 Qt 4 最大的一个区别之一是底层架构 ...
- Qt 学习之路 2(67):访问网络(3)
Qt 学习之路 2(67):访问网络(3) 豆子 2013年11月5日 Qt 学习之路 2 16条评论 上一章我们了解了如何使用我们设计的NetWorker类实现我们所需要的网络操作.本章我们将继续完 ...
- Qt 学习之路 2(66):访问网络(2)
Home / Qt 学习之路 2 / Qt 学习之路 2(66):访问网络(2) Qt 学习之路 2(66):访问网络(2) 豆子 2013年10月31日 Qt 学习之路 2 27条评论 上一 ...
随机推荐
- android 4.0.4系统下实现apk的静默安装和启动
转 android 4.0.4系统下实现apk的静默安装和启动 分类: Android 2013-02-14 14:13 1762人阅读 评论(10) 收藏 举报 最近在android 4.0.4系统 ...
- python3导入自定义模块
模块是个好东西啊,大牛们开源共享许多模块也加快了大家开发的速度,许多开源模块可以在这里找到 ↓ https://pypi.python.org/pypi 因为刚入门所有有很多细节不懂,在网上搜寻资料的 ...
- Spring总结九:事务管理机制
何为事务 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如SQL ...
- conda create -n AlphaPose2018 python=2.7
conda create -n AlphaPose2018 python=2.7Solving environment: done ==> WARNING: A newer version of ...
- Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.38/images/json: dial unix /var/run/docker.sock: conne
使用docker报如下错误信息: Got permission denied while trying to connect to the Docker daemon socket at unix:/ ...
- SHELL读取 ini 格式文件做配置文件
ini文件格式一般都是由节.键.值三部分组成 格式: [第一节 ] 第一个键 = 值 第二个键 = 第二个值 [第二节 ] 第一个键 = val1,val2,val3 例子: [COM] KINGGO ...
- 无返回值的函数如何捕获出错情况(检查errno常量)
在执行这个函数前,先清除errno,函数返回时,检查errno常量. 每次程序调用失败的时候,系统会自动用用错误代码填充errno这个全局变量,这样你只需要读errno这个全局变量就可以获得失败原因了 ...
- 使用mail架包发送邮件javax.mail.AuthenticationFailedException: failed to connect at javax.mail.Service.connec
这个错误是因为连接不上邮箱服务器导致的,可能有以下几个原因(以网易邮箱为例) 1.当使用第三方登录邮箱时需要有邮箱的授权码,且要开启POP3/SMTP/IMAP:服务 2.在代码中要调用网易邮箱的密码 ...
- leetcode N-Queens I && N-Queens II
第一个的代码: #include<iostream> #include<vector> using namespace std; bool isLegal(int i, int ...
- HBuilder生成代码行快捷键
1.在body内输入div.abc按下tab键 效果:<div class="abc"></div> 2.在body内输入div#abc按下tab键 效果: ...