最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt入門學習之數據庫操作指南

 更新時間:2022年08月11日 14:45:19   作者:塵客-追夢  
Qt SQL模塊為數據庫提供了編程支持,Qt支持很多種常見的數據庫,如 MySQL Oracle、MS SQL Server、SQLite等,下面這篇文章主要介紹了這篇文章主要給大家介紹了關于Qt入門學習之數據庫操作指南的相關資料,需要的朋友可以參考下

一、數據庫

Qt中的Qt SQL模塊提供了對數據庫的支持,模塊中類可分為三層:驅動層,sql接口層,用戶層。

  • 驅動層:(QSqlDriver,QSqlDriverCreator,QSqlDriverCreatorBase,QSqlDriverPlugin)為具體的數據庫和SQL接口層之間提供了底層的橋梁;
  • SQL接口層:(QSqlDatabase,QSqlQuery,QSqlError,QSqlRecord)提供了對數據庫的訪問,其中QSqlDatabase類用來創(chuàng)建連接,QSqlQuery類可以使用SQL語句來實現與數據庫交互;
  • 用戶接口層:(QSqlTableModel,QSqlQueryModel,QSqlRelationalTableModel)實現了將數據庫中的數據鏈接到窗口部件上,這些類是使用模型/視圖框架實現的,它們是更高層次的抽象;

1.數據庫驅動

Qt SQL模塊使用數據庫驅動插件來和不同的數據庫接口進行通信。由于Qt SQL模塊的接口是獨立于數據庫的,所以所有數據庫特定的代碼都包含在了這些驅動中。Qt默認支持一些驅動:

驅動名稱數據庫
QSQLITE2SQLite2版本
QSQLITESQLite3版本
QMYSQLMySQL
QODBCSQL Service
QPSQLPostgreSQL(>=7.3版本)

2.查詢驅動

#include <QApplication>
#include <QSqlDatabase>
#include <QDebug>
#include <QStringList>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QStringList drivers = QSqlDatabase::drivers();
    foreach(QString driver, drivers)
        qDebug() << driver;
    return a.exec();
}

在.pro文件中加入sql模塊

3.連接數據庫

數據庫連接使用連接名來定義,而不是使用數據庫名,可以向相同的數據庫創(chuàng)建多個連接。QSqlDatabase也支持默認連接的概念,默認連接就是一個沒有命名的連接。在使用QSqlQuery或者QSqlQueryModel的成員函數時需要指定一個連接名作為參數,如果沒有指定,那么就會使用默認連接。

原型:QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const
QString &connectionName = QLatin1String( defaultConnection ))

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1");
db.setDatabaseName("book");
db.setUserName("root");
db.setPassword("123456");
if(!db.open())
{
	qDebug() << "fail to connect mysql" << db.lastError().text();
}

創(chuàng)建兩個名為“first”和“second”的連接:

QSqlDatabase firstDB = QSqlDatabase::addDatabase("QMYSQL", "first");
QSqlDatabase secondDB = QSqlDatabase::addDatabase("QMYSQL", "second");

創(chuàng)建完連接后,可以在任何地方使用QSqlDatabase::database()靜態(tài)函數通過連接名稱獲取指向數據庫連接的指針,如果調用該函數時沒有指明連接名稱,那么會返回默認連接,例如:

QSqlDatabase defaultDB = QSqlDatabase::database();
QSqlDatabase firstDB = QSqlDatabase::database("first");
QSqlDatabase secondDB = QSqlDatabase::database("second");

要移除一個數據庫連接,需要先使用QSqlDatabase::close()關閉數據庫,然后使用靜態(tài)函數QSqlDatabase::removeDatabase()移除該連接。

連接SQL Server數據庫

QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName(QString("DRIVER={SQL SERVER}SERVER=%1;DATABASE=%2;UID=%3;PWD=%4;")
                   .arg("IP").arg("dbname").arg("user").arg("password"));
bool ok =db.open();

連接SQLite數據庫

QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE");
db1.setHostName("IP");
db1.setDatabaseName("dbname");
db1.setUserName("user");
db1.setPassword("password");

4.執(zhí)行sql語句

QSqlQuery類提供了一個接口,用于執(zhí)行SQL語句和瀏覽查詢的結果集。要執(zhí)行一個SQL語句,只需要簡單的創(chuàng)建一個QSqlQuery對象,然后調用QSqlQuery::exec()函數即可。

QSqlQuery query;
query.exec("select * from student");

QSqlQuery提供了對結果集的訪問,可以一次訪問一條記錄。當執(zhí)行完exec()函數后,QSqlQuery的內部指針會位于第一條記錄前面的位置。必須調用一次QSqlQuery::next()函數來使其前進到第一條記錄,然后可以重復使用next()函數來訪問其他的記錄,直到該函數的返回值為false,

while(query.next())
{  
	qDebug() << query.value(0).toInt() << query.value(1).toString();  
}

在QSqlQuery類中提供了多個函數來實現在結果集中進行定位,比如next()定位到下一條記錄,previous()定位到前一條記錄,first()定位的第一條記錄,last()定位到最后一條記錄,seek(n)定位到第n條記錄。當前行的索引可以使用at()返回;record()函數可以返回當前指向的記錄。

5.插入數據

插入一條記錄

query.exec("insert into student (id, name) values (1, 'LI')");

同一時間插入多條記錄,可以使用占位符來完成。Qt支持兩種占位符:名稱綁定和位置綁定。

1名稱綁定

query.prepare("insert into student (id, name) values (:id, :name)");
int idValue = 1;
QString nameValue = "Li";
query.bindValue(":id", idValue);
query.bindValue(":name", nameValue);
query.exec();

2位置綁定

query.prepare("insert into student (id, name) values (?, ?)");
int idValue = 1;
QString nameValue = "Li";
query.addBindValue(idValue);
query.addBindValue(nameValue);
query.exec();

當要插入多條記錄時,只需要調用QSqlQuery::prepare()一次,然后使用多次bindValue()或者addBindValue()函數來綁定需要的數據,最后調用一次exec()函數就可以了。其實,進行多條數據插入時,還可以使用批處理進行:

query.prepare("insert into student (id, name) values (?, ?)");
QVariantList ids;
ids << 1 << 2 << 3;
query.addBindValue(ids);
QVariantList names;
names << "Li" << "Wang" << "Liu";
query.addBindValue(names);
if(!query.execBatch()) 
qDebug() << query.lastError();

6.事務

事務可以保證一個復雜的操作的原子性,就是對于一個數據庫操作序列,這些操作要么全部做完,要么一條也不做,是不可分割的工作單位。如果底層的數據庫引擎支持事務,QSqlDriver::hasFeature(QSqlDriver::Transactions)會返回true。可以使用QSqlDatabase::transaction()來啟動一個事務,然后編寫希望在事務中執(zhí)行的SQL語句,最后調用QSqlDatabase::commit()提交或者QSqlDatabase::rollback()回滾。使用事務必須在創(chuàng)建查詢以前就開始事務

QSqlDatabase::database().transaction();
QSqlQuery query;
query.exec("SELECT id FROM student WHERE name = 'Li'");
if (query.next())
{
	int id = query.value(0).toInt();
    query.exec("INSERT INTO project (id, name, ownerid) "
               "VALUES (201, 'MProject', "
               + QString::number(id) + ')');
}
QSqlDatabase::database().commit();

二 ,sql模型類

Qt還提供了3個更高層的類來訪問數據庫,分別是QSqlQueryModel、QSqlTableModel和QSqlRelationalTableModel。
這3個類都是從QAbstractTableModel派生來的,可以很容易地實現將數據庫中的數據在QListView和QTableView等項視圖類中進行顯示。使用這些類的另一個好處是,這樣可以使編寫的代碼很容易的適應其他的數據源。例如,如果開始使用了QSqlTableModel,而后來要改為使用XML文件來存儲數據,這樣需要做的僅是更換一個數據模型

1.QSqlQueryModel模型

QSqlQueryModel提供了一個基于SQL查詢的只讀模型。

QSqlQueryModel *model = new QSqlQueryModel(this);
model->setQuery("select * from student");
model->setHeaderData(0, Qt::Horizontal, tr("學號"));
model->setHeaderData(1, Qt::Horizontal, tr("姓名"));
model->setHeaderData(2, Qt::Horizontal, tr("課程"));
ui->tableView->setModel(model);
ui->tableView->verticalHeader()->setHidden(true);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

先創(chuàng)建了QSqlQueryModel對象,然后使用setQuery()來執(zhí)行SQL語句查詢整張student表,并使用setHeaderData()來設置顯示的標頭。后面創(chuàng)建了視圖,并將QSqlQueryModel對象作為其要顯示的模型。這里要注意,其實QSqlQueryModel中存儲的是執(zhí)行完setQuery()函數后的結果集,所以視圖中顯示的是結果集的內容。QSqlQueryModel中還提供了columnCount()返回一條記錄中字段的個數;rowCount()返回結果集中記錄的條數;record()返回第n條記錄;index()返回指定記錄的指定字段的索引;clear()可以清空模型中的結果集。

2.QSqlTableModel模型

QSqlTableModel提供了一個一次只能操作一個SQL表的讀寫模型,它是QSqlQuery的更高層次的替代品,可以瀏覽和修改獨立的SQL表,并且只需編寫很少的代碼,而且不需要了解SQL語法。
創(chuàng)建數據表

QSqlQuery query;
// 創(chuàng)建student表
query.exec("create table student (id int primary key, "
                       "name varchar, course int)");
query.exec("insert into student values(1, '李', 10)");
query.exec("insert into student values(2, '馬', 11)");
query.exec("insert into student values(3, '孫', 12)");
// 創(chuàng)建course表
query.exec("create table course (id int primary key, "
                       "name varchar, teacher varchar)");
query.exec("insert into course values(10, '數學', '王老師')");
query.exec("insert into course values(11, '英語', '張老師')");
query.exec("insert into course values(12, '計算機', '李老師')");

顯示表:

QSqlTableModel *model = new QSqlTableModel(this);
model->setTable("student");
model->select();
// 設置編輯策略
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
ui->tableView->setModel(model);
ui->tableView->verticalHeader()->setHidden(true);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

創(chuàng)建一個QSqlTableModel后,只需使用setTable()來為其指定數據庫表,然后使用select()函數進行查詢,調用這兩個函數就等價于執(zhí)行了“select * from student”語句。這里還可以使用setFilter()來指定查詢時的條件。在使用該模型以前,一般還要設置其編輯策略,它由QSqlTableModel::EditStrategy枚舉類型定義。

常量描述
QSqlTableModel::OnFieldChange所有對模型的改變都會立即應用到數據庫
QSqlTableModel::OnRowChange對一條記錄的改變會在用戶選擇另一條記錄時被應用
QSqlTableModel::OnManualSubmit所有的改變都會在模型中進行緩存,直到調用submitAll()或者reverAll()函數

修改

// 開始事務操作
    model->database().transaction();
    if (model->submitAll())
    {
        if(model->database().commit()) // 提交
            QMessageBox::information(this, tr("tableModel"),tr("數據修改成功!"));
    } else
    {
        model->database().rollback(); // 回滾
        QMessageBox::warning(this, tr("tableModel"),tr("數據庫錯誤: %1").arg(model->lastError().text()),QMessageBox::Ok);
    }

撤銷修

model->revertAll();

查詢

//全部數據
model->setTable("student");
model->select();
//進行篩選
QString name = "xxx" ;
// 根據姓名進行篩選,一定要使用單引號
model->setFilter(QString("name = '%1'").arg(name));
model->select();

升序

//id字段,即第0列,升序排列
model->setSort(0, Qt::AscendingOrder);
model->select();

刪除

    // 獲取選中的行
    int curRow = ui->tableView->currentIndex().row();
    // 刪除該行
    model->removeRow(curRow);
    int ok1 = QMessageBox::warning(this,tr("刪除當前行!"),
                tr("你確定刪除當前行嗎?"), QMessageBox::Yes, QMessageBox::No);
    if(ok == QMessageBox::No)
    { // 如果不刪除,則撤銷
        model->revertAll();
    } else { // 否則提交,在數據庫中刪除該行
        model->submitAll();
    }

3.QSqlRelationalTableModel模型

QSqlRelationalTableModel繼承自QSqlTableModel,并且對其進行了擴展,提供了對外鍵的支持。一個外鍵就是一個表中的一個字段和其他表中的主鍵字段之間的一對一的映射。例如,student表中的course字段對應的是course表中的id字段,那么就稱字段course是一個外鍵。因為這里的course字段的值是一些數字,這樣的顯示很不友好,使用關系表格模型,就可以將它顯示為course表中的name字段的值。

QSqlRelationalTableModel *model = new QSqlRelationalTableModel(this);
model->setTable("student");
model->setRelation(2, QSqlRelation("course", "id", "name"));
model->select();
ui->tableView->setModel(model);
ui->tableView->verticalHeader()->setHidden(true);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

Qt中還提供了一個QSqlRelationalDelegate委托類,它可以為QSqlRelationalTableModel顯示和編輯數據。這個委托為一個外鍵提供了一個QComboBox部件來顯示所有可選的數據,這樣就顯得更加清晰了。

view->setItemDelegate(new QSqlRelationalDelegate(view));

總結 

到此這篇關于Qt入門學習之數據庫操作指南的文章就介紹到這了,更多相關Qt數據庫操作內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++連連看判定圖形消除算法

    C++連連看判定圖形消除算法

    這篇文章主要為大家詳細介紹了C++連連看判定圖形消除算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C++控制臺實現貪吃蛇游戲

    C++控制臺實現貪吃蛇游戲

    這篇文章主要為大家詳細介紹了C++控制臺實現貪吃蛇,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語言自定義數據類型的結構體、枚舉和聯合詳解

    C語言自定義數據類型的結構體、枚舉和聯合詳解

    這篇文章主要給大家介紹了關于C語言自定義數據類型的結構體、枚舉和聯合的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • 一文弄懂C語言如何實現單鏈表

    一文弄懂C語言如何實現單鏈表

    單鏈表是由多個結點鏈接組成,它的每個結點包含兩個域,一個數據域和一個鏈接域(地址域),下面這篇文章主要給大家介紹了關于C語言如何實現單鏈表的相關資料,需要的朋友可以參考下
    2021-09-09
  • C++?boost?thread庫用法詳細講解

    C++?boost?thread庫用法詳細講解

    Boost是為C++語言標準庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標準庫的后備,是C++標準化進程的開發(fā)引擎之一,是為C++語言標準庫提供擴展的一些C++程序庫的總稱
    2022-11-11
  • C語言中字符串庫函數的實現及模擬

    C語言中字符串庫函數的實現及模擬

    C語言中有很多數據類型,比如int(整數類型)、char(字符類型)、以及浮點型的double(雙精度)等。但是有一點就是我們發(fā)現這里并沒有提到我們常見的有關字符串的類型。本文為大家介紹了C語言中字符串庫函數的實現及模擬,需要的可以參考一下
    2022-11-11
  • VC解析XML文件-CMarkup的使用詳解

    VC解析XML文件-CMarkup的使用詳解

    本篇文章是對VC解析XML文件-CMarkup的使用進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 淺析C++中類模板的用法

    淺析C++中類模板的用法

    C++類模板是一種用于創(chuàng)建通用類的工具,它允許我們定義一個通用類,支持多種類型。本文就來簡單講講它的具體使用吧,感興趣的可以了解一下
    2023-04-04
  • static關鍵字的作用詳解

    static關鍵字的作用詳解

    在C語言中,static的字面意思很容易把我們導入歧途,其實它的作用有三條。
    2013-04-04
  • STL 的string類怎么啦

    STL 的string類怎么啦

    在我們研究string類犯了什么毛病之前,還讓我先說一下如何了解一個C++的類。我們要了解一個C++的類,一般來說,要從三個方面入手
    2013-11-11

最新評論

当阳市| 高陵县| 镇雄县| 南阳市| 甘洛县| 富源县| 北京市| 疏附县| 新竹市| 岗巴县| 大化| 肇源县| 油尖旺区| 湄潭县| 高安市| 莱阳市| 太谷县| 平顶山市| 依兰县| 冕宁县| 商都县| 亳州市| 嘉峪关市| 济阳县| 延长县| 南涧| 宣威市| 家居| 南京市| 德州市| 绩溪县| 应城市| 南充市| 育儿| 贞丰县| 上林县| 垫江县| 阿合奇县| 元朗区| 南木林县| 曲松县|