數據查詢模塊在整個系統中難度最低,因爲Qt對數據庫操做的封裝堪稱完美,因此各類查詢都是手到擒來,不費吹灰之力。Qt中內置了sqlite數據庫,你能夠在數據庫插件目錄sqldrivers發現qsqlite.dll文件比較大,大概800KB左右,而qsqlmysql.dll才70KB,按道理mysql確定比sqlite要大才對,後面查閱資料發現越來Qt源碼中已經包含了sqlite的源碼,編譯的時候直接內置進去了。這樣就大大方便用戶使用sqlite數據庫了,不像mysql等其餘數據庫還須要帶上對應數據庫的動態庫文件。其實安卓系統中也大量使用sqlite數據庫,足以見得sqlite數據庫是有多麼的方便。Qt中的數據庫通訊都在qtsql模塊中,主要經常使用的就是qsqlquery和qsqltablemodel這兩個類了,一個用來執行sql語句,別看qsqlquery字面上的意思是查詢,其實還包括了添加、刪除、修改(基本術語簡稱增刪改)等,反正他能夠執行任意的sql語句,只要數據庫支持的話,若是有結果返回,會提供一個結果集返回,能夠循環遍歷取出結果。數據庫處理基本上是四個點叫增刪改查,這些都是對應的sql語句,具體sql教程推薦能夠看這裏https://www.w3school.com.cn/sql/index.asp。我的作數據庫相關的項目以來,除了基本的增刪改查之外,基本上就是要注意三點:第一點索引,第二點數據庫事務,第三點數據庫翻頁。mysql
第一點索引,說到數據庫查詢,不得不說很重要的東西,那就是索引,不少初學者都反應查詢好慢啊,才幾十萬的數據量,就慢成這樣子,一問原來沒有加索引的緣故,這個知識點通用於任何開發語言而並非qt獨有,這是數據庫相關的知識點,強烈建議在數據庫建表的時候,若是是經常使用的須要查詢的表,尤爲是用到where條件語句的表,必須加上索引,至於索引的字段,建議使用經常使用的條件的字段,這樣在查詢的時候速度飛快,索引就至關於新華字典的部首目錄或者音節目錄,這樣能夠快速定位具體位置。linux
第二點數據庫事務,加了索引查詢是變快了不少,在這種幾十萬的數據量下,基本上是瞬間忽略不計,也要看具體的字段的數量和每一個字段的字節數長度等,若是是幾百個字段,那另當別論,不過通常不建議一個表的字段數量特別多,那樣無法管理,太難了。索引是加快了查詢速度,也會帶來一些負面影響好比數據庫文件體積變大,基本上會變大50%,不過如今的存儲器那麼大,基本上沒有太大關係,查詢是快了,不少初學者又抱怨這Qt真垃圾,添加幾百條數據要好久好久,若是是幾千條更是卡爆了,這個又是另一個重要知識點數據庫事務,通常對於大量的數據更新,好比插入數據或者更新數據等,建議開啓數據庫事務,這樣處理之後哪怕一次性插入一萬條數據,也是很是快的。代碼以下:git
//啓動數據庫事務 QSqlDatabase::database().transaction(); int count = sqls.count(); for (int i = 0; i < count; i++) { QSqlQuery query; query.exec(sqls.at(i)); } //提交數據庫事務 bool ok = QSqlDatabase::database().commit(); if (!ok) { QSqlDatabase::database().rollback(); }
第三點數據庫翻頁,因爲常常作數據庫相關的項目,其實大部分的項目,注意只要是項目不是那種調試工具級別的小demo,多多少少都會涉及到記錄存儲等,這就須要用到數據庫,記錄查詢這塊,少不了分頁顯示查詢結果,不論是何種開發語言,各類程序員都會封裝本身的一套通用的數據庫翻頁代碼,毫無疑問我也封裝了一套輪子,重複利用,我甚至封裝了上一頁下一頁按鈕+當前記錄數等標籤的功能,只要傳入對應控件的指針便可,此代碼開源。程序員
通用翻頁組件源碼地址:https://gitee.com/feiyangqingyun/QWidgetDemo https://github.com/feiyangqingyun/QWidgetDemo
文件名稱:dbpagegithub
體驗地址:https://gitee.com/feiyangqingyun/QWidgetExe https://github.com/feiyangqingyun/QWidgetExe
文件名稱:bin_sams.zipweb
void frmDataNode::initData() { whereSql = "where 1=1"; columnNames << "編號" << "位號" << "控制器名稱" << "探測器名稱" << "濃度值" << "氣體符號" << "保存時間"; columnWidths << 60 << 100 << 130 << 130 << 60 << 70 << 150; if (App::WorkMode == 2) { columnNames[5] = "符號"; } //設置須要顯示數據的表格和翻頁的按鈕,最後一列自動填充,奇偶行不一樣顏色顯示 dbPage = new DbPage(this); dbPage->setAllCenter(true); dbPage->setColumnNames(columnNames); dbPage->setColumnWidths(columnWidths); dbPage->setResultCurrent(App::PageCount); dbPage->setTableName("NodeLog"); dbPage->setOrderSql(QString("LogID %1").arg(App::NodeLogOrder)); dbPage->setControl(ui->tableView, ui->labPageCount, ui->labPageCurrent, ui->labResultCount, ui->labResultCurrent, ui->labResult, 0, ui->btnFirst, ui->btnPre, ui->btnNext, ui->btnLast, "LogID"); dbPage->setWhereSql(whereSql); dbPage->select(); } void frmDataNode::on_btnSelect_clicked() { QDateTime dateStart = ui->dateStart->dateTime(); QDateTime dateEnd = ui->dateEnd->dateTime(); if (dateStart > dateEnd) { QUIHelper::showMessageBoxError("開始時間不能大於結束時間!", 3); return; } //構建SQL語句 QString sql = "where 1=1"; if (ui->ckTimeStart->isChecked()) { if (App::LocalDBType.toUpper() == "SQLITE") { sql += " and datetime(SaveTime)>='" + dateStart.toString("yyyy-MM-dd HH:mm:ss") + "'"; sql += " and datetime(SaveTime)<='" + dateEnd.toString("yyyy-MM-dd HH:mm:ss") + "'"; } else if (App::LocalDBType.toUpper() == "MYSQL") { sql += " and unix_timestamp(SaveTime)>=unix_timestamp('" + dateStart.toString("yyyy-MM-dd HH:mm:ss") + "')"; sql += " and unix_timestamp(SaveTime)<=unix_timestamp('" + dateEnd.toString("yyyy-MM-dd HH:mm:ss") + "')"; } } if (ui->ckDeviceName->isChecked()) { sql += " and DeviceName='" + ui->cboxDeviceName->currentText() + "'"; } if (ui->ckNodeName->isChecked()) { sql += " and NodeName='" + ui->cboxNodeName->currentText() + "'"; } if (ui->ckPositionID->isChecked()) { sql += " and PositionID='" + ui->txtPositionID->text() + "'"; } //綁定數據到表格 whereSql = sql; dbPage->setWhereSql(whereSql); dbPage->select(); }