Qt 提供了 QtSql 模組來提供平臺獨立的基於 SQL 的資料庫操作。這裡我們所說的“平臺
獨立”,既包括作業系統平臺,也包括各個資料庫平臺,Qt支援以下幾種資料庫:
- QT自帶SQLITE資料庫,不需要再安裝
- QTDS在Qt4.7起已經被移除
1.QtSql
要使用QtSql 模組的話,需要在.pro檔案中新增這麼一句:
QT += sql
2.QSqlDatabase
QSqlDatabase類提供了一個介面,用於通過連線訪問資料。QSqlDatabase的一個例項表示連線。該連線通過受支援的資料庫驅動程式之一提供對資料庫的訪問,該驅動程式派生自QSqlDriver。
2.1 建立一個資料庫示例如下
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("scooters.dat"); //如果本目錄下沒有該檔案,則會在本目錄下生成,否則連線該檔案 if (!db.open()) { QMessageBox::warning(0, QObject::tr("Database Error"), db.lastError().text()); return false; }
編譯執行後,可以看到已經建立了該檔案:
建立成功後,該檔案預設為空的,然後就可以使用QSqlQuery類來操作該資料庫, QSqlQuery類使用的是SQL語句,如果只需要使用高層次的資料
庫介面(不關心 SQL 語法),我們可以選擇 QSqlTableModel 和
QSqlRelationalTableModel(在後續章節介紹)。本章我們介紹
QSqlQuery 類,來如何使用SQL語法.
3.QSqlQuery類介紹
通過exec()成員函式來執行DML(資料操作語言)語句,如SELECT、INSERT、UPDATE和DELETE,以及DDL(資料定義語言)語句等.
比如:
QSqlQuery query; query.exec("DROP TABLE students"); //刪除名為students的表
4.接下來,我們講講如何匯入資料
建立表:
query.exec("CREATE TABLE students (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "name VARCHAR(40) NOT NULL, " " score INTEGER NOT NULL, " "class VARCHAR(40) NOT NULL)"); //建立一個students表,標題分別為id、name、score、class
" PRIMARY KEY AUTOINCREMENT,":表示該列為整數遞增,如果為空時則自動填入1,然後在下面的每一行都會自動+1, PRIMARY KEY則表示該列作為列表的主鍵,通過它可以輕易地獲取某一行資料
" INTEGER ":表示該列為帶符號的整數
" VARCHAR(40) ":表示該列為可變長字串,預設只能儲存英文和數字或者utf-8,最多儲存40個位元組.
"NOT NULL ":表示該列的內容不為空
匯入資料:
query.exec("INSERT INTO students (name, score,class) " "VALUES ('小張', 85, '初2-1班')"); //向students表裡的(name, score,class)標題下插入一項資料'小張', 85, '初2-1班'
新增後如下圖所示:
5.批量匯入庫
如果我們有大串資料需要匯入時,也可以使用prepare()來綁值,然後再通過bindValue()向綁值加入資料
示例程式碼如下所示:
QStringList names; names<<"小A"<<"小B"<<"小C"<<"小D"<<"小E"<<"小F"<<"小G" <<"小H"<<"小I"<<"小G"<<"小K"<<"小L"<<"小M"<<"小N"; QStringList clases; clases<<"初1-1班"<<"初1-2班"<<"初1-3班"<<"初2-1班" <<"初2-2班"<<"初2-3班"<<"初3-1班"<<"初3-2班"<<"初3-3班"; QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("students.dat"); //在本目錄下生成 QSqlQuery query; query.exec("DROP TABLE students"); //先清空一下表 query.exec("CREATE TABLE students (" "id INTEGER PRIMARY KEY AUTOINCREMENT, " "name VARCHAR(40) NOT NULL, " " score INTEGER NOT NULL, " "class VARCHAR(40) NOT NULL)"); //建立一個students表 query.prepare("INSERT INTO students (name, score,class) " "VALUES (:name, :score, :class)"); //為每一列標題新增繫結值 foreach (QString name, names) //從names表裡獲取每個名字 { query.bindValue(":name", name); //向繫結值里加入名字 query.bindValue(":score", (qrand() % 101)); //成績 query.bindValue(":class", clases[qrand()%clases.length()] ); //班級 query.exec(); //加入庫中 }
執行後,通過SQLite工具開啟students.dat,如下圖所示:
6.查詢表內容
我們對上圖生成的students.dat檔案進行查詢內容時,則需要使用WHERE 關鍵字實現.
示例-查詢成績值為60~80之間的學生:
query.exec("SELECT * FROM students WHERE score >= 60 AND score <= 80;"); while(query.next()) { QString id = query.value(0).toString(); QString name = query.value(1).toString(); QString score = query.value(2).toString(); QString classs = query.value(3).toString(); qDebug()<<id<<name<<score<<classs; }
執行列印:
當然還有其它語句,比如:
"SELECT * FROM students WHERE score >= 80 OR class == '初3-3班';" //判斷成績大於等於80,或者班級為初3-3班的
列印如下圖所示:
"SELECT * FROM students WHERE class GLOB '*3-3*';" // GLOB表示萬用字元,匹配班級帶有"3-3"的名字
列印如下圖所示:
PS:如果想查詢所有內容,則改為 query.exec("SELECT * FROM students ");
7.刪表內容
刪表內容有3個語句:
- DROP: 用來刪除整表,並且連表結構也會刪除,刪除後則只能使用CREATE TABLE來重新建立表
- TRUNCATE: 在SQLite中沒有該語句,在MySQL中有該語句,用來清楚表內資料,但是表結構不會刪除.
- DELETE: 刪除部分記錄,並且表結構不會刪除,刪除的速度比上面兩個語句慢,可以配合WHERE來刪除指定的某行
示例1
query.exec("DELETE FROM students"); //刪除students表裡所有內容
刪除後如下圖所示:
示例2-刪除id=3的一行
query.exec("DELETE FROM students WHERE id = 3");
刪除前:
刪除後:
8.改表內容
改表內容一般用下面兩個語句:
- UPDATE : 用來修改表中內容,可以通過WHERE語句來指定修改
- ALTER TABLE: 用來重新命名錶,或者在已有的表中新增新的一列
8.1 ALTER 示例
示例1
query.exec("ALTER TABLE students RENAME TO new_students"); //將students重新命名為new_students
執行後如下圖所示:
示例2
query.exec("ALTER TABLE new_students ADD COLUMN 結果 VARCHAR(10)"); //向 new_students表裡新增新的一列,標題為結果,內容格式為VARCHAR
執行後如下圖所示:
8.2 UPDATE 示例
示例1-不使用WHERE,直接修改某列
query.exec("UPDATE new_students SET score = 100 , name = '小A'"); //修改score和name所在的列內容
修改後如下圖所示:
示例2-使用WHERE,判斷小於60的設為不合格,否則設為合格
query.exec("UPDATE new_students SET 結果='不合格' WHERE score<60 "); query.exec("UPDATE new_students SET 結果='合格' WHERE score>=60 ");
修改前如下圖所示:
修改後: