不管是在哪使用資料庫,終歸是需要學習sql語言的,所以還沒學的小夥伴建議打道回府先去把資料庫學了再來看。
我自己將QT中一些常用的資料庫分為內部資料庫和外部資料庫。這所謂的內部資料庫就是像“SQLite”這種大部分使用場景是嵌入式的,它將整個資料庫儲存在一個單一的檔案中,沒有獨立的資料庫伺服器程序。應用程式直接使用它來管理資料,資料庫引擎作為應用程式的一部分執行,它適用於小型專案,這樣的好處就是不需要單獨的資料庫伺服器,。而外部伺服器也就是我們常說的“Mysql”“oracle”“PostgreSQL”等,說白了就是在開發過程中接入QT外部的資料庫。
總結一下來說內部資料庫就是在開發過程中將資料庫整合到應用程式中,非常適合小專案以及嵌入式專案開發。而外部資料庫是一個單獨的個體,需要應用程式連線外部資料庫使用的,適合於大專案,什麼是大專案應該不用我說吧。再從另一方面來說像SQLite這種我們定義為輕量級資料庫,它保留一些像oracle一些大型資料庫的部分功能變為體積更小的“資料庫青春版”。之所以不直接講像Mysql這種大體積的資料庫是因為QT中本身就嵌入了SQlite,我們在開發小專案的時候是不需要安裝並配置動態庫的。
本章要講的內容我也會分為內部資料庫和外部資料庫來講:
一、內部資料庫(SQLite)
(一)sql模組
和網路程式設計一樣,我們新建立的預設專案後,需要手動在.pro手動新增sql,這樣我們才能程式碼中引用與資料庫相關的庫類。
(二)資料庫在QT中使用的整個流程
對於資料庫而言不管是在什麼專案裡面還是用什麼技術開發與資料庫相關的技術時使用資料庫的步驟大致是差不多的。如下:
1、建立資料庫物件(資料庫例項化)
2、連線資料庫
3、使用資料庫(平常說的增、刪、改、查)
4、關閉資料庫
(三)QT帶給我們的一些運算元據庫的api
1、資料庫操作
QSqlDatabase
該類提供對資料庫操作行為的各種函式,其中包括建立、刪除、複製和關閉資料庫。
2、表資料操作
說句老實話,QT中資料庫操作有這兩個類就可以完成大部分資料庫的操作。無非就是連線資料庫和運算元據庫表資料這兩種而已。像後面需要羅列的行資料記錄和列資料記錄這都是為了簡化開發步驟的函式,需要記得太多了。作為初學者搞懂這兩個類的使用就可以了,剩下的在開發工作中慢慢積累。
QSqlQuery
該類提供一些組合用來執行sql語句。
(四)類使用和實操程式碼
1、模組新增
QT += sql
2、api新增
講解部分我都給寫進程式碼註釋裡面了,直接下載看或者github上面線上看。
運算元據庫有這三個就大致夠了。第一個進行資料庫本身的操作,也就是建立或者刪除資料庫操作,建表刪表等。
第二個進行資料的操作,也就是表中儲存的資料。但前兩者本質還是使用的sql語言。
第三個看名字就知道一種報錯機制。如果我們在開發工程中遇到資料庫的使用問題就可以使用這個類來輸出報錯內容,我個人覺得這是非常重要的一個類。天下苦bug久已!!!
#include <QSqlDatabase>
#include <QSqlQuery>
//#include <QDebug>
#include <QSqlError>
3、檢查QT框架中有哪些資料庫
drivers是QT中的一個靜態函式,用於返回系統上可用的資料庫驅動列表。使用這個函式我們就可以在控制檯裡面輸出QT可用的資料庫驅動。
QSqlDatabase::drivers
qDebug()<<QSqlDatabase::drivers()<<endl;//使用方法
00:30:27: Starting /home/xiaochenggk/QT/build-QSql-Desktop_Qt_5_12_12_GCC_64bit-Debug/QSql ...
Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.
("QSQLITE", "QMARIADB", "QMYSQL", "QMYSQL3") //控制檯輸出內容
輸出內容中括號裡就是可用資料庫的列表,可以看到除開sqlite以外還有mysql可以使用。這裡提一句,QT中從QT5開始就不再內嵌除開sqlite的驅動了,所以如果我們需要使用外部資料庫的時候需要自己去新增其他資料庫驅動。這裡輸出列表中的mysql就是我自己手動新增的資料庫驅動,正常是不會出現mysql的。
而且不管是內部資料庫還是外部資料庫他們在QT中的配置程式碼和sql語言都是差不多的(唯一不同就是需要多一些配置,類似於賬號密碼的操作登入資料庫再連線)。後面講外部資料庫的時候我只會教一下如何編譯資料庫驅動和安裝資料庫。
4、建立資料庫連線
使用addDatabase指定資料庫驅動,也就是說指定使用什麼資料庫。再由setDatabaseName來指定資料庫檔案存放的本地檔案地址,如果指定的位置沒有已存在的檔案QT會自動給你建立一個。再使用open連線資料庫,這一個完整的步驟就算完成了。
來看看程式碼部分:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");//指定資料庫驅動
db.setDatabaseName("資料庫檔案地址,例如/home/xiaochenggk/QT_Sqlite_project");
//指定資料庫檔案的存放地址
if (!db.open()) {//這裡你可以單獨把db.open()拿出來執行,我這樣寫的好處
//可以透過一套輸出語句來判斷資料庫是否連線成功
qDebug() << "無法開啟資料庫:" << db.lastError().text();
return;
}
5、資料操作
(1)建立表
前面都是使用QSqlDatabase操作的資料庫的內容,這裡對資料的操作就需要使用QSqlQuery裡面的內容了。
我們來試試建立表,在資料庫結構中,表才是真正意義上用來存放資料的結構,建立的資料庫也是用來存放表。建立資料我們需要建立一個QSqlQuery物件,之後建立一個變數用來儲存sql語句將這個變數傳給QSqlQuery的exec函式執行就可以了,這樣一個建立表的工作就算是完成。核心函式為exec。
QSqlQuery query;//QSqlQuery物件
QString createTable = "CREATE TABLE IF NOT EXISTS students ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"name TEXT, "
"age INTEGER)";//使用變數來儲存一段sql語句,以供給
//後續工作使用
if (!query.exec(createTable)) {//這裡就是將createTable的值傳給exec
qDebug() << "建立表失敗:" << query.lastError().text();
}
(2)增
建好表以後就要往表裡面插入資料了。後面我也按照增刪改查的順序一個一個的都寫個例子照著寫就行,主要還是需要自己學習sql語言。
第一行使用QSqlQuery中的prepare函式執行一個帶有佔位符的sql語句,然後二三句addBindValue用於向佔位符繫結實際的值,確保sql語句中的佔位符可以插入正確的值。之所以這麼寫,考慮到ui介面輸入資料可以直接插入資料庫中,然後addBindValue中的值可以跟一個lineEdit控制元件繫結,將lineEdit輸入的值傳給佔位符。
query.prepare("INSERT INTO students (name, age) VALUES (?, ?)");
query.addBindValue("Alice");
query.addBindValue(22);
if (!query.exec()) {
qDebug() << "插入資料失敗:" << query.lastError().text();
}
到這裡不難看出建立表的時候和插入資料的時候對exec使用有些不一樣。建立表時exec是有一個值傳入的,而插入資料的時候並還沒有,這是因為exec函式的使用有兩種方式。一種就如建立表的時候一樣直接傳值使用,或者直接exec函式中給一個sql語句。而第二種就是結合prepare和addBindValue一起使用,由這兩個函式寫好的sql語句,程式碼中是不需要直接給exec傳值的。
(3)刪
query.prepare("DELETE FROM students WHERE name = ?");
query.addBindValue("Alice");
if (!query.exec()) {
qDebug() << "刪除資料失敗:" << query.lastError().text();
}
(4)改
query.prepare("UPDATE students SET age = ? WHERE name = ?");
query.addBindValue(23); // 更新後的年齡
query.addBindValue("Alice"); // 要更新的學生名字
if (!query.exec()) {
qDebug() << "更新資料失敗:" << query.lastError().text();
}
(5)查
query.exec("SELECT * FROM students");
while (query.next()) {
QString name = query.value("name").toString();
int age = query.value("age").toInt();
qDebug() << "學生:" << name << ", 年齡:" << age;
}
(6)關閉資料庫
db.close();
二、外部資料庫(Mysql)
外部資料庫大部分內容和sqlite是類似的,或者說是資料庫的操作是一樣的。但是與sqlite不同的是mysql或者說所有外部資料庫是需要類似於賬戶密碼的驗證過程的。
db.setHostName("localhost"); // 資料庫主機名
db.setDatabaseName("my_database"); // 資料庫名稱
db.setUserName("root"); // 資料庫使用者名稱
db.setPassword("password"); // 資料庫密碼