Qt數(shù)據(jù)庫(kù) 利用QSqlQuery類(lèi)執(zhí)行SQL語(yǔ)句 上篇
本文介紹的是Qt數(shù)據(jù)庫(kù) 利用QSqlQuery類(lèi)執(zhí)行SQL語(yǔ)句,是本文要介紹的內(nèi)容,SQL即結(jié)構(gòu)化查詢(xún)語(yǔ)言,是關(guān)系數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)語(yǔ)言。前面已經(jīng)提到,在Qt中利用QSqlQuery類(lèi)實(shí)現(xiàn)了執(zhí)行SQL語(yǔ)句。需要說(shuō)明,我們這里只是Qt教程,而非專(zhuān)業(yè)的數(shù)據(jù)庫(kù)教程,所以我們不會(huì)對(duì)數(shù)據(jù)庫(kù)中的一些知識(shí)進(jìn)行深入講解,下面只是對(duì)最常用的幾個(gè)知識(shí)點(diǎn)進(jìn)行講解。
我們下面先建立一個(gè)工程,然后講解四個(gè)知識(shí)點(diǎn),分別是:
1、操作SQL語(yǔ)句返回的結(jié)果集。
2、在SQL語(yǔ)句中使用變量。
3、批處理操作。
4、事務(wù)操作。
我們新建Qt4 Gui Application工程,我這里工程名為query ,然后選中QtSql模塊,(注:在新版的Qt Creator中可能沒(méi)有模塊選擇頁(yè)面,我們需要手動(dòng)在.pro工程文件中添加代碼“QT += sql” )Base class選QWidget。工程建好后,添加C++ Header File ,命名為connection.h ,更改其內(nèi)容如下:
- #ifndef CONNECTION_H
 - #define CONNECTION_H
 - #include <QMessageBox>
 - #include <QSqlDatabase>
 - #include <QSqlQuery>
 - static bool createConnection()
 - {
 - QSqlDatabase db = QSqlDatabase::addDatabase(“QSQLITE”);
 - db.setDatabaseName(“:memory:”);
 - if (!db.open()) {
 - QMessageBox::critical(0, qApp->tr(“Cannot open database”),
 - qApp->tr(“Unable to establish a database connection.”
 - ), QMessageBox::Cancel);
 - return false;
 - }
 - QSqlQuery query;
 - query.exec(“create table student (id int primary key, ”
 - “name varchar(20))”);
 - query.exec(“insert into student values(0, ‘first’)”);
 - query.exec(“insert into student values(1, ‘second’)”);
 - query.exec(“insert into student values(2, ‘third’)”);
 - query.exec(“insert into student values(3, ‘fourth’)”);
 - query.exec(“insert into student values(4, ‘fifth’)”);
 - return true;
 - }
 - #endif // CONNECTION_H
 
然后更改main.cpp的內(nèi)容如下:
- #include <QtGui/QApplication>
 - #include “widget.h”
 - #include “connection.h”
 - int main(int argc, char *argv[])
 - {
 - QApplication a(argc, argv);
 - if (!createConnection())
 - return 1;
 - Widget w;
 - w.show();
 - return a.exec();
 - }
 
可以看到,我們是在主函數(shù)中打開(kāi)數(shù)據(jù)庫(kù)的,而數(shù)據(jù)庫(kù)連接用一個(gè)函數(shù)完成,并單獨(dú)放在一個(gè)文件中,這樣的做法使得主函數(shù)很簡(jiǎn)潔。我們今后使用數(shù)據(jù)庫(kù)時(shí)均使用這種方法。我們打開(kāi)數(shù)據(jù)庫(kù)連接后,新建了一個(gè)學(xué)生表,并在其中插入了幾條記錄。
表中的一行就叫做一條記錄,一列是一個(gè)屬性。這個(gè)表共有5條記錄,id和name兩個(gè)屬性。程序中的“id int primary key”表明id屬性是主鍵,也就是說(shuō)以后添加記錄時(shí),必須有id項(xiàng)。
下面我們打開(kāi)widget.ui文件,在設(shè)計(jì)器中向界面上添加一個(gè)Push Button ,和一個(gè)Spin Box 。將按鈕的文本改為“查詢(xún)”,然后進(jìn)入其單擊事件槽函數(shù),更改如下。
- void Widget::on_pushButton_clicked()
 - {
 - QSqlQuery query;
 - query.exec(“select * from student”);
 - while(query.next())
 - {
 - qDebug() << query.value(0).toInt() << query.value(1).toString();
 - }
 - }
 
我們?cè)趙idget.cpp中添加頭文件:
- #include <QSqlQuery>
 - #include <QtDebug>
 
然后運(yùn)行程序,單擊“查詢(xún)”按鈕,效果如下:
可以看到在輸出窗口,表中的所有內(nèi)容都輸出出來(lái)了。這表明我們的數(shù)據(jù)庫(kù)連接已經(jīng)成功建立了。
操作SQL語(yǔ)句返回的結(jié)果集。
在上面的程序中,我們使用query.exec(“select * from student”);來(lái)查詢(xún)出表中所有的內(nèi)容。其中的SQL語(yǔ)句“select * from student”中“*”號(hào)表明查詢(xún)表中記錄的所有屬性。而當(dāng)query.exec(“select * from student”);這條語(yǔ)句執(zhí)行完后,我們便獲得了相應(yīng)的執(zhí)行結(jié)果,因?yàn)楂@得的結(jié)果可能不止一條記錄,所以我們稱(chēng)之為結(jié)果集。
結(jié)果集其實(shí)就是查詢(xún)到的所有記錄的集合,而在QSqlQuery類(lèi)中提供了多個(gè)函數(shù)來(lái)操作這個(gè)集合,需要注意這個(gè)集合中的記錄是從0開(kāi)始編號(hào)的。最常用的有:
seek(int n) :query指向結(jié)果集的第n條記錄。
first() :query指向結(jié)果集的第一條記錄。
last() :query指向結(jié)果集的最后一條記錄。
next() :query指向下一條記錄,每執(zhí)行一次該函數(shù),便指向相鄰的下一條記錄。
previous() :query指向上一條記錄,每執(zhí)行一次該函數(shù),便指向相鄰的上一條記錄。
record() :獲得現(xiàn)在指向的記錄。
value(int n) :獲得屬性的值。其中n表示你查詢(xún)的第n個(gè)屬性,比方上面我們使用“select * from student”就相當(dāng)于“select id, name from student”,那么value(0)返回id屬性的值,value(1)返回name屬性的值。該函數(shù)返回QVariant類(lèi)型的數(shù)據(jù),關(guān)于該類(lèi)型與其他類(lèi)型的對(duì)應(yīng)關(guān)系,可以在幫助中查看QVariant。
at() :獲得現(xiàn)在query指向的記錄在結(jié)果集中的編號(hào)。
需要說(shuō)明,當(dāng)剛執(zhí)行完query.exec(“select * from student”);這行代碼時(shí),query是指向結(jié)果集以外的,我們可以利用query.next(),當(dāng)?shù)谝淮螆?zhí)行這句代碼時(shí),query便指向了結(jié)果集的第一條記錄。當(dāng)然我們也可以利用seek(0)函數(shù)或者first()函數(shù)使query指向結(jié)果集的第一條記錄。但是為了節(jié)省內(nèi)存開(kāi)銷(xiāo),推薦的方法是,在query.exec(“select * from student”);這行代碼前加上query.setForwardOnly(true);這條代碼,此后只能使用next()和seek()函數(shù)。
下面將“查詢(xún)”按鈕的槽函數(shù)更改如下:
- void Widget::on_pushButton_clicked()
 - {
 - QSqlQuery query;
 - query.exec(“select * from student”);
 - qDebug() << “exec next() :”;
 - if(query.next())
 - //開(kāi)始就先執(zhí)行一次next()函數(shù),那么query指向結(jié)果集的第一條記錄
 - {
 - int rowNum = query.at();
 - //獲取query所指向的記錄在結(jié)果集中的編號(hào)
 - int columnNum = query.record().count();
 - //獲取每條記錄中屬性(即列)的個(gè)數(shù)
 - int fieldNo = query.record().indexOf(“name”);
 - //獲取”name”屬性所在列的編號(hào),列從左向右編號(hào),最左邊的編號(hào)為0
 - int id = query.value(0).toInt();
 - //獲取id屬性的值,并轉(zhuǎn)換為int型
 - QString name = query.value(fieldNo).toString();
 - //獲取name屬性的值
 - qDebug() << “rowNum is : ” << rowNum //將結(jié)果輸出
 - << ” id is : ” << id
 - << ” name is : ” << name
 - << ” columnNum is : ” << columnNum;
 - }
 - qDebug() << “exec seek(2) :”;
 - if(query.seek(2))
 - //定位到結(jié)果集中編號(hào)為2的記錄,即第三條記錄,因?yàn)榈谝粭l記錄的編號(hào)為0
 - {
 - qDebug() << “rowNum is : ” << query.at()
 - << ” id is : ” << query.value(0).toInt()
 - << ” name is : ” << query.value(1).toString();
 - }
 - qDebug() << “exec last() :”;
 - if(query.last())
 - //定位到結(jié)果集中最后一條記錄
 - {
 - qDebug() << “rowNum is : ” << query.at()
 - << ” id is : ” << query.value(0).toInt()
 - << ” name is : ” << query.value(1).toString();
 - }
 - }
 
然后在widget.cpp文件中添加頭文件。
- #include <QSqlRecord>
 
運(yùn)行程序,結(jié)果如下:
本文章原創(chuàng)于www.yafeilinux.com
小結(jié):Qt數(shù)據(jù)庫(kù) 利用QSqlQuery類(lèi)執(zhí)行SQL語(yǔ)句 上篇 的內(nèi)容后介紹完了,希望本文對(duì)你有幫助!要想深入了解數(shù)據(jù)庫(kù)的話(huà),請(qǐng)參考


















 
 
 

 
 
 
 