#(56):使用模型操作數據庫
前一章我們使用 SQL?語句完成了對數據庫的常規操作,包括簡單的 CREATE、SELECT?等語句的使用。我們也提到過,Qt?不僅提供了這種使用 SQL?語句的方式,還提供了一種基于模型的更高級的處理方式。這種基于`QSqlTableModel`?的模型處理更為高級,如果對 SQL?語句不熟悉,并且不需要很多復雜的查詢,這種`QSqlTableModel`模型基本可以滿足一般的需求。本章我們將介紹`QSqlTableModel`的一般使用,對比 SQL 語句完成對數據庫的增刪改查等的操作。值得注意的是,`QSqlTableModel`并不一定非得結合?`QListView`或`QTableView`使用,我們完全可以用其作一般性處理。
首先我們來看看如何使用`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;
}
~~~
我們依舊使用了前一章的`connect()`函數。接下來我們創建了`QSqlTableModel`實例,使用`setTable()`函數設置所需要操作的表格;`setFilter()`函數則是添加過濾器,也就是 WHERE 語句所需要的部分。例如上面代碼中的操作實際相當于 SQL 語句
~~~
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();
~~~
插入也很簡單:`model.insertRows(row, 1);`說明我們想在索引 0 的位置插入 1 行新的數據。使用`setData()`函數則開始準備實際需要插入的數據。注意這里我們向 row 的第一個位置寫入 Cheng(通過`model.index(row, 1)`,回憶一下,我們把 model 當作一個二維表,這個坐標相當于第 row 行第 1 列),其余以此類推。最后,調用`submitAll()`函數提交所有修改。這里執行的操作可以用如下 SQL 表示:
~~~
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();
}
}
~~~
這段代碼中,我們首先找到 age = 25 的記錄,然后將 age 重新設置為 26,存入相同的位置(在這里都是索引 0 的位置),提交之后完成一次更新。當然,我們也可以類似其它模型一樣的設置方式:`setData()`函數。具體代碼片段如下:
~~~
if (model.select()) {
if (model.rowCount() == 1) {
model.setData(model.index(0, 2), 26);
model.submitAll();
}
}
~~~
注意我們的 age 列是第 3 列,索引值為 2,因為前面還有 id 和 name 兩列。這里的更新操作則可以用如下 SQL 表示:
~~~
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();
}
}
~~~
如果使用 SQL 則是:
~~~
DELETE FROM student WHERE age = 25
~~~
當我們看到`removeRows()`函數就應該想到:我們可以一次刪除多行。事實也正是如此,這里不再贅述。
- (1)序
- (2)Qt 簡介
- (3)Hello, world!
- (4)信號槽
- (5)自定義信號槽
- (6)Qt 模塊簡介
- (7)MainWindow 簡介
- (8)添加動作
- (9)資源文件
- (10)對象模型
- (11)布局管理器
- (12)菜單欄、工具欄和狀態欄
- (13)對話框簡介
- (14)對話框數據傳遞
- (15)標準對話框 QMessageBox
- (16)深入 Qt5 信號槽新語法
- (17)文件對話框
- (18)事件
- (19)事件的接受與忽略
- (21)事件過濾器
- (22)事件總結
- (23)自定義事件
- (24)Qt 繪制系統簡介
- (25)畫刷和畫筆
- (26)反走樣
- (27)漸變
- (28)坐標系統
- (29)繪制設備
- (30)Graphics View Framework
- (31)貪吃蛇游戲(1)
- (32)貪吃蛇游戲(2)
- (33)貪吃蛇游戲(3)
- (34)貪吃蛇游戲(4)
- (35)文件
- (36)二進制文件讀寫
- (37)文本文件讀寫
- (38)存儲容器
- (39)遍歷容器
- (40)隱式數據共享
- (41)model/view 架構
- (42)QListWidget、QTreeWidget 和 QTableWidget
- (43)QStringListModel
- (44)QFileSystemModel
- (45)模型
- (46)視圖和委托
- (47)視圖選擇
- (48)QSortFilterProxyModel
- (49)自定義只讀模型
- (50)自定義可編輯模型
- (51)布爾表達式樹模型
- (52)使用拖放
- (53)自定義拖放數據
- (54)剪貼板
- (55)數據庫操作
- (56)使用模型操作數據庫
- (57)可視化顯示數據庫數據
- (58)編輯數據庫外鍵
- (59)使用流處理 XML
- (60)使用 DOM 處理 XML
- (61)使用 SAX 處理 XML
- (62)保存 XML
- (63)使用 QJson 處理 JSON
- (64)使用 QJsonDocument 處理 JSON
- (65)訪問網絡(1)
- (66)訪問網絡(2)
- (67)訪問網絡(3)
- (68)訪問網絡(4)
- (69)進程
- (70)進程間通信
- (71)線程簡介
- (72)線程和事件循環
- (73)Qt 線程相關類
- (74)線程和 QObject
- (75)線程總結
- (76)QML 和 QtQuick 2
- (77)QML 語法
- (78)QML 基本元素
- (79)QML 組件
- (80)定位器
- (81)元素布局
- (82)輸入元素
- (83)Qt Quick Controls
- (84)Repeater
- (85)動態視圖
- (86)視圖代理
- (87)模型-視圖高級技術
- (88)Canvas
- (89)Canvas(續)