Qt 数据库操作(二)
文章目錄
- 執(zhí)行SQL語句
- 1、執(zhí)行一個查詢
- 2、瀏覽結(jié)果集
- 3、插入、更新和刪除記錄
- 4、事務(wù)
執(zhí)行SQL語句
1、執(zhí)行一個查詢
QSqlQuery類提供了一個接口,用于執(zhí)行SQL語句和瀏覽查詢的結(jié)果集。
要執(zhí)行一個SQL語句,只需要簡單地創(chuàng)建一個QSqlQuery 對象,然后調(diào)用QSqlQuery::exec()函數(shù)即可。
例如:
QSqlQuery query:
query.exec(“select * from student”);
在QSqlQuery的構(gòu)造函數(shù)中可以接受一個可選的QSqlDatabase對象來指定使用哪一個數(shù)據(jù)庫連接。 當(dāng)沒有指定連接時,就是默認(rèn)連接。
如果發(fā)生了錯誤,那么exec()函數(shù)會返回false, 可以使用QSqlQuery::lastError()來獲取錯誤信息。
2、瀏覽結(jié)果集
QsqlQuery 提供了對結(jié)果集的訪問,可以一次訪問一條記錄。當(dāng)執(zhí)行完exec()函數(shù)后,QSqlQuery的內(nèi)部指針會位于第一條記錄前面的位置。必須調(diào)用一次QSqlQuery:next()函數(shù)來使其前進(jìn)到第一條記錄,然后可以重復(fù)使用next()函數(shù)來訪問其他的記錄,直到該函數(shù)的返回值為false。遍歷一個結(jié)果集:
while(query1.next())
{qDebug() << query1.value(0).toInt() << query1.value(1).toString(); }在QSqlquery類中提供了多個函數(shù)來實(shí)現(xiàn)在結(jié)果集中進(jìn)行定位,比如:
next()定位到下一條記錄。
previous 定位到前一條記錄;
first () 定位到第一條記錄;
seek()定位到第n條記錄;
at()返回當(dāng)前行的索引;
record()函數(shù)可以返回當(dāng)前指向的記錄里;
size()返回結(jié)果集中的總行數(shù)。
QSqlDriver::hasFeature() 數(shù)據(jù)庫支持的特性。
項(xiàng)目示例:
#ifndef CONNECTION_H#define CONNECTION_H #include <QMessageBox> #include <QSqlDatabase> #include <QSqlQuery>static bool createConnection() {// 創(chuàng)建一個數(shù)據(jù)庫連接,使用“connection1”為連接名QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "connection1");db1.setDatabaseName("my1.db");if (!db1.open()) {QMessageBox::critical(0, "Cannot open database1","Unable to establish a database connection.", QMessageBox::Cancel);return false;}// 這里要指定連接QSqlQuery query1(db1);query1.exec("create table student (id int primary key, ""name varchar(20))");query1.exec("insert into student values(0, 'LiMing')");query1.exec("insert into student values(1, 'LiuTao')");query1.exec("insert into student values(2, 'WangHong')");// 創(chuàng)建另一個數(shù)據(jù)庫連接,要使用不同的連接名,這里是“connection2”QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "connection2");db2.setDatabaseName("my2.db");if (!db2.open()) {QMessageBox::critical(0, "Cannot open database1","Unable to establish a database connection.", QMessageBox::Cancel);return false;}// 這里要指定連接QSqlQuery query2(db2);query2.exec("create table student (id int primary key, ""name varchar(20))");query2.exec("insert into student values(10, 'LiQiang')");query2.exec("insert into student values(11, 'MaLiang')");query2.exec("insert into student values(12, 'ZhangBin')");return true; }#endif // CONNECTION_H #include <QApplication>#include <QSqlDatabase> #include <QDebug> #include <QStringList> #include "connection.h" #include <QVariant> #include <QSqlDriver> #include <QSqlRecord> #include <QSqlField>int main(int argc, char *argv[]) {QApplication a(argc, argv);// 創(chuàng)建數(shù)據(jù)庫連接if (!createConnection()) return 1;// 使用QSqlQuery查詢連接1的整張表,先要使用連接名獲取該連接QSqlDatabase db1 = QSqlDatabase::database("connection1");QSqlQuery query1(db1);qDebug() << "connection1:";query1.exec("select * from student");while(query1.next()){qDebug() << query1.value(0).toInt() << query1.value(1).toString();}// 使用QSqlQuery查詢連接2的整張表QSqlDatabase db2 = QSqlDatabase::database("connection2");QSqlQuery query2(db2);qDebug() << "connection2:";query2.exec("select * from student");while(query2.next()){qDebug() << query2.value(0).toInt() << query2.value(1).toString();} // 以下是在例程17-4中添加的代碼int numRows;// 先判斷該數(shù)據(jù)庫驅(qū)動是否支持QuerySize特性,如果支持,則可以使用size()函數(shù),// 如果不支持,那么就使用其他方法來獲取總行數(shù)if (db2.driver()->hasFeature(QSqlDriver::QuerySize)) {qDebug() << "has feature: query size";numRows = query2.size();} else {qDebug() << "no feature: query size";query2.last();numRows = query2.at() + 1;}qDebug() << "row number: " << numRows;// 指向索引為1的記錄,即第二條記錄query2.seek(1);// 返回當(dāng)前索引值qDebug() << "current index: " << query2.at();// 獲取當(dāng)前行的記錄QSqlRecord record = query2.record();// 獲取記錄中“id”和“name”兩個屬性的值int id = record.value("id").toInt();QString name = record.value("name").toString();qDebug() << "id: " << id << "name: " << name;// 獲取索引為1的屬性,即第二個屬性QSqlField field = record.field(1);// 輸出屬性名和屬性值,結(jié)果為“name”和“MaLiang”qDebug() << "second field: " << field.name()<< "field value: " << field.value().toString();return a.exec(); }3、插入、更新和刪除記錄
插入一條記錄:
query2.exec(“insert into student (id, name) values (100, chenyun)”);
插入多條記錄:
// 下面是與上面代碼等價的名稱綁定實(shí)現(xiàn)代碼// query2.prepare("insert into student (id, name) values (:id, :name)");// int idValue = 100;// QString nameValue = "ChenYun";// query2.bindValue(":id", idValue);// query2.bindValue(":name", nameValue);// query2.exec();// 下面是與上面代碼等價的位置綁定實(shí)現(xiàn)代碼// query2.prepare("insert into student (id, name) values (?, ?)");// int idValue = 100;// QString nameValue = "ChenYun";// query2.addBindValue(idValue);// query2.addBindValue(nameValue);// query2.exec();// 批處理query2.prepare("insert into student (id, name) values (?, ?)");QVariantList ids;ids << 20 << 21 << 22;query2.addBindValue(ids);QVariantList names;names << "xiaoming" << "xiaoliang" << "xiaogang";query2.addBindValue(names);if(!query2.execBatch()) qDebug() << query2.lastError();對于記錄的更新和刪除,它們和插入操作是相似的,并且也可以使用占位符。
**// 更新**query2.exec("update student set name = 'xiaohong' where id = 20"); **// 刪除** query2.exec("delete from student where id = 21");query2.exec("select * from student"); while(query2.next()) {qDebug() << query2.value(0).toInt() << query2.value(1).toString(); }4、事務(wù)
事務(wù)可以保證一個復(fù)雜操作的原子性。就是對于一個數(shù)據(jù)庫的操作序列,這些操作要么全部做完,要么一條也不做,它是一個不可分割的工作單位。
在Qt中,如果底層的數(shù)據(jù)庫引擎支持事務(wù),那么
QSqlDatabase::hasFeature(QSqlDriver::Transactions)會返回true。
可以使用QSqlDatabase::transaction()來啟動一個事務(wù),
然后編寫一些希望在事務(wù)中執(zhí)行的SQL語句,
最后調(diào)用QSqlDatabase::commit()或者QSqlDatabase::rollback()。
當(dāng)使用事務(wù)時必須在創(chuàng)建查詢以前就開始事務(wù),例如:
QSqlDatabase::database().transaction();
QSqlQuery query3;
query3.exec(“SELECT ID FROM employee WHERE name = Torid Halvorsen”);
if(query3.next())
{
int employeeId = query3.value(0).toInt();
query3.exec(“INSERT INTO project(id,name,ownerid)” “VALUES(201,Manhattan Project,”+ QString::number(employeeId)+"")");
}
QSqlDatabase::database().commit();
本文檔整理來源自《QtCreator 快速入門》。。。。
總結(jié)
以上是生活随笔為你收集整理的Qt 数据库操作(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt 事件系统的解读
- 下一篇: Qt数据库操作(三) -- 使用SQL模