Qt數(shù)據(jù)庫相關(guān)應用開發(fā)總結(jié)
一、前言
近期花了兩個多月時間,將數(shù)據(jù)庫相關(guān)的代碼重新封裝成了各種輪子(這條路必須打通,打通以后,相關(guān)項目只需要引入這個組件pri即可),測試了從Qt4.7到Qt6.1的各種版本,測試了odbc、sqlite、mysql、postgresql、sqlserver、oracle、人大金倉等數(shù)據(jù)庫,測試了本地連接、遠程連接、阿里云連接等,測試了windows、linux、mac等系統(tǒng),將所有項目數(shù)據(jù)庫相關(guān)的代碼全部更新了一遍。能夠兼容這么多Qt版本和數(shù)據(jù)庫插件以及測試驗證系統(tǒng),估計全網(wǎng)也沒幾個人,全國11W Qter開發(fā)者中應該也是最多不超過10人。
二、數(shù)據(jù)庫開發(fā)經(jīng)驗總結(jié)
在數(shù)據(jù)庫相關(guān)的應用中,如果僅僅是單機版本,沒有特別的需要(比如領(lǐng)導指定,或者需要遠程存放數(shù)據(jù)),強烈建議使用sqlite數(shù)據(jù)庫,這是本人經(jīng)過無數(shù)次的對比測試和N個商業(yè)項目應用得出的結(jié)論。
Qt天生內(nèi)置了sqlite數(shù)據(jù)庫,只需要發(fā)布的時候帶上插件就行(可以看到插件動態(tài)庫文件比其他幾種都要大,那是因為直接將數(shù)據(jù)庫的源碼都編譯進去了,而其他只編譯了中間通信交互的插件源碼),其他數(shù)據(jù)庫要么還要帶上動態(tài)庫,要么還需要創(chuàng)建數(shù)據(jù)源;速度上,絕對無與倫比的出類拔萃,同樣的數(shù)據(jù)庫結(jié)構(gòu)(表結(jié)構(gòu)、索引等完全一致),查詢速度和批量更新速度、數(shù)據(jù)庫事務等,速度都是其他幾種的至少3倍以上,而且隨著數(shù)據(jù)量的增大對比越發(fā)明顯;
幾千萬的數(shù)據(jù)量完全沒問題,而且速度和性能都還可以,不要以訛傳訛網(wǎng)上部分菜雞說的不支持百萬以上的數(shù)據(jù)量,本人親測億級別,數(shù)據(jù)量建議千萬級別以下,著重注意數(shù)據(jù)庫表和索引的設(shè)計;
其他數(shù)據(jù)庫還要注意版本的區(qū)別,ODBC數(shù)據(jù)源形式還容易出錯和執(zhí)行失敗;
sqlite數(shù)據(jù)庫也有幾個重大缺點:不支持加密,不支持網(wǎng)絡訪問,不支持部分數(shù)據(jù)庫高級特性,不支持海量數(shù)據(jù)(億級別以上),但是對于絕大部分Qt項目還是足夠;
數(shù)據(jù)庫支持友好度大致是 sqlite > postgresql > mysql > odbc ;
以上都是在Qt環(huán)境中個人測試得出的結(jié)論,結(jié)果未必正確,作為參考即可,其他編程環(huán)境比如C#、JAVA請忽略,也許差別可能在中間通信的效率造成的;
三、數(shù)據(jù)庫連接說明
- Qt5默認提供的數(shù)據(jù)庫插件包括了QSQLITE、QMYSQL、QPSQL、QODBC四種,后期版本比如5.12開始把mysql也移除了(可能是因為開源協(xié)議的問題),其中驅(qū)動打印中還有個QMYSQL3是表示mysql3舊版本,現(xiàn)在默認一般都mysql5以上,QPSQL7表示postgres7舊版本,現(xiàn)在默認一般都postgres9以上。
- 根據(jù)字面意思很容易理解QSQLITE用來連接sqlite數(shù)據(jù)庫,QMYSQL用來連接mysql數(shù)據(jù)庫,QPSQL用來連接postgres數(shù)據(jù)庫,QODBC理論上可以用來連接任何支持ODBC數(shù)據(jù)源的數(shù)據(jù)庫,比如access、sqlserver、mysql、postgres、oracle等。
- Qt4默認提供的數(shù)據(jù)庫插件只有QSQLITE、QODBC兩種,因為QODBC理論上可以用來連接任何支持ODBC數(shù)據(jù)源的數(shù)據(jù)庫,只是通過了微軟的數(shù)據(jù)源中間件,效率上可能會有損耗,所以在Qt5又新增了其他幾個常用數(shù)據(jù)庫的插件比如QMYSQL、QPSQL,而其他數(shù)據(jù)庫由于協(xié)議的要求并沒有提供對應的插件需要自行編譯比如oracle。
- Qt內(nèi)置了sqlite數(shù)據(jù)庫,可以觀察到qsqlite4.dll文件大小明顯比其他數(shù)據(jù)庫插件大很多,理論上光一個插件應該小很多才對,畢竟sqlite屬于小型數(shù)據(jù)庫,所以肯定是將sqlite的源碼直接編譯到插件了,所以我們在使用sqlite數(shù)據(jù)庫的時候無需帶一個sqlite.dll,而使用mysql則需要帶上libmysql.dll。
- 使用mysql、postgres等支持遠程訪問的數(shù)據(jù)庫的時候,并不需要本地安裝數(shù)據(jù)庫,只需要發(fā)布程序的時候帶上對應數(shù)據(jù)庫的動態(tài)庫即可,比如mysql對應帶上libmysql.dll即可,這樣程序指定數(shù)據(jù)庫主機地址就可以連接上,比如阿里云的mysql、postgres等云端數(shù)據(jù)庫。
- mysql、posgrest等支持遠程連接的數(shù)據(jù)庫,默認安裝以后出于安全性考慮只支持本地訪問,需要做設(shè)置才能支持遠程訪問,mysql需要增加用戶root@%即主機設(shè)置為%,postgres需要打開安裝目錄下的C:\PostgreSQL\10\data\pg_hba.conf文件,增加一行 host all all 192.168.1.0/24 md5 表示支持192.168.1.1到192.168.1.255的IP訪問,同時將C:\PostgreSQL\10\data\postgresql.conf改成listen_addresses = '*'表示支持所有地址,具體這個的含義可以自行搜索。
- mysql數(shù)據(jù)庫通信的默認端口是3306,postgres的是5432,這些端口都可以在安裝的時候或者后期更改。
- 數(shù)據(jù)庫也有位數(shù)的區(qū)別,比如你連接的是64位的數(shù)據(jù)庫那就需要用64位的Qt以及64位的數(shù)據(jù)庫插件和對應的動態(tài)庫文件,位數(shù)一定要完全一致才行,否則連不上,很多人會在這個地方摔一跤。除了位數(shù)的區(qū)別可能還要注意版本的區(qū)別,畢竟數(shù)據(jù)庫一直在更新升級換代,有些版本變動比較大,未必Qt發(fā)布版本的時候?qū)椭С肿钚碌臄?shù)據(jù)庫,所以一般建議用稍微老一點的數(shù)據(jù)庫版本,比如mysql本人一直用5.6,測試到現(xiàn)在Qt5.13版本都支持。
- 一般的軟件默認都只需要連接一個數(shù)據(jù)庫,所以建議直接在程序啟動以后就打開好數(shù)據(jù)庫,然后其他需要用到數(shù)據(jù)庫的地方就執(zhí)行即可,最后程序關(guān)閉的時候關(guān)閉數(shù)據(jù)庫。很多初學者每次增刪改查都打開數(shù)據(jù)庫執(zhí)行完成操作以后然后關(guān)閉數(shù)據(jù)庫,這樣效率極其低下。如果需要連接多個數(shù)據(jù)庫,則以數(shù)據(jù)庫連接名稱作為區(qū)分,Qt支持同時多個數(shù)據(jù)庫連接的,數(shù)據(jù)庫跨線程不安全,要加鎖,所以建議在哪個線程使用到的數(shù)據(jù)庫就在那個線程中打開,而不要主線程打開數(shù)據(jù)庫子線程使用數(shù)據(jù)庫,很可能會出問題。Qt5.10開始增加了數(shù)據(jù)庫跨線程使用的安全性檢查,運行時會打印提示。
- 創(chuàng)建數(shù)據(jù)庫、創(chuàng)建表、創(chuàng)建索引、初始化數(shù)據(jù)等這些都可以通過執(zhí)行sql語句來實現(xiàn),強烈建議在對常用的數(shù)據(jù)量比較多的表創(chuàng)建表的時候要創(chuàng)建索引,在大量的數(shù)據(jù)查詢更新操作的時候先啟動數(shù)據(jù)庫事務,執(zhí)行完成以后提交數(shù)據(jù)庫事務。
四、數(shù)據(jù)庫操作流程代碼
void MainWindow::testDb()
{
//打印當前Qt對應支持的數(shù)據(jù)庫驅(qū)動名稱
qDebug() << QSqlDatabase::drivers();
//創(chuàng)建數(shù)據(jù)庫對象,驅(qū)動名稱根據(jù)打印的填寫,"QSQLITE", "QMYSQL", "QMYSQL3", "QODBC", "QODBC3", "QPSQL", "QPSQL7"
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
//設(shè)置數(shù)據(jù)庫參數(shù),要查看Qt文檔是否支持該數(shù)據(jù)庫,一般建議默認的就好不用設(shè)置
//db.setConnectOptions("MYSQL_OPT_RECONNECT=1;MYSQL_OPT_CONNECT_TIMEOUT=1;");
//設(shè)置數(shù)據(jù)庫的主機地址
db.setHostName("127.0.0.1");
//設(shè)置數(shù)據(jù)庫通信端口,默認值 mysql:3306 postgres:5432 sqlserver:1433
db.setPort(5433);
//設(shè)置數(shù)據(jù)庫名稱,默認值 mysql:mysql postgres:postgres sqlserver:master
//如果是sqlite數(shù)據(jù)庫只需要設(shè)置這個參數(shù)即可,其余參數(shù)都不用設(shè)置,因為sqlite不需要主機端口和用戶
//參數(shù)內(nèi)容為數(shù)據(jù)庫文件的路徑 db.setDatabaseName("c:/test.db");
db.setDatabaseName("postgres");
//設(shè)置登錄用戶名稱,默認值 mysql:root postgres:postgres sqlserver:sa
db.setUserName("postgres");
//設(shè)置登錄用戶密碼
db.setPassword("admin");
//打開數(shù)據(jù)庫,如果失敗打印錯誤信息
if (!db.open()) {
qDebug() << db.lastError();
return;
}
//執(zhí)行增刪改查
//常規(guī)查詢語句
QString sql = "select UserName,UserPwd from UserInfo";
//帶條件+排序+分組的查詢語句
sql = "select UserName,UserPwd from UserInfo where UserName='admin' order by UserName asc group by UserGroup";
//構(gòu)建查詢對象,傳入sql語句查詢,可以先判斷執(zhí)行成功與否再來取值
QSqlQuery query;
if (query.exec(sql)) {
//循環(huán)取出所有查詢結(jié)果,對應結(jié)果是QVariant類型可以自行to到其他類型
while(query.next()) {
qDebug() << query.value(0).toString() << query.value(1).toString();
}
}
//添加數(shù)據(jù),拼接字符串的形式比較通用,還有占位符的形式
sql = "insert into UserInfo(UserName,UserPwd) values('ceshi', '12345')";
//刪除數(shù)據(jù),如果不加where條件則表示刪除整個表的數(shù)據(jù)
sql = "delete from UserInfo where UserName='ceshi'";
//更新數(shù)據(jù),如果不加where條件則表示更新整個表的數(shù)據(jù)
sql = "update UserInfo set UserPwd='admin123' where UserName='ceshi'";
//可以復用上面的QSqlQuery對象,也可以重新new,復用的話需要先調(diào)用clear
query.clear();
//添加+刪除+更新 數(shù)據(jù)只需要知道執(zhí)行成功與否就行
if (!query.exec(sql)) {
qDebug() << "執(zhí)行sql語句失敗";
}
//關(guān)閉數(shù)據(jù)庫,程序自動關(guān)閉的時候也會關(guān)閉,所以只是用一個數(shù)據(jù)庫的情況下無需手動關(guān)閉
db.close();
}五、數(shù)據(jù)庫綜合應用組件
(一)功能特點
- 同時支持多種數(shù)據(jù)庫比如odbc、sqlite、mysql、postgresql、sqlserver、oracle、人大金倉等。
- 一個數(shù)據(jù)庫類即可管理本地數(shù)據(jù)庫通信,也支持遠程數(shù)據(jù)庫通信等。
- 數(shù)據(jù)庫線程支持執(zhí)行各種sql語句,包括單條和批量。
- 組件中的所有類打印信息、錯誤信息、執(zhí)行結(jié)果都信號發(fā)出去。
- 集成數(shù)據(jù)庫通用翻頁類(負責具體處理邏輯),搭配分頁導航控件(負責外觀),形成超級牛逼的翻頁控件。
- 集成數(shù)據(jù)庫自動清理類,設(shè)定最大記錄數(shù)后臺自動清理早期數(shù)據(jù)。
- 集成自定義委托類,支持復選框、文本框、下拉框、日期框、微調(diào)框、進度條等。
- 同時支持Qt4-Qt6,親測Qt4.6到Qt6.1任意版本,任意系統(tǒng)和編譯器。
- 本組件無故障 360天7乘24小時 運行在至少上萬個現(xiàn)場,商業(yè)級別品質(zhì)保證。
- 每個類都對應完整詳細的使用示例,注釋詳細,非常適合閱讀學習。
- 可以作為獨立的程序運行,比如自動清理早期數(shù)據(jù),同步數(shù)據(jù)到云端。
- 全部線程處理,不卡界面,自動重連數(shù)據(jù)庫。
- 普通測試情況,sqlite數(shù)據(jù)庫,數(shù)據(jù)庫發(fā)生器每秒鐘插入1000條記錄約0.003秒鐘,同時自動清理數(shù)據(jù)類每秒鐘刪除1000條記錄約0.13秒,不同線程互不干擾。
(二)數(shù)據(jù)庫通信管理線程類
- 可設(shè)置數(shù)據(jù)庫類型,支持多種數(shù)據(jù)庫類型。
- 數(shù)據(jù)庫類型包括但不限于odbc、sqlite、mysql、postgresql、sqlserver、oracle、人大金倉等。
- 可設(shè)置數(shù)據(jù)庫連接信息包括主機地址、用戶信息等。
- 具有自動重連機制,可設(shè)置是否檢查連接以及檢查間隔。
- 支持單條sql語句隊列,一般用于查詢返回數(shù)據(jù),每次插入一條執(zhí)行一條。
- 支持多條sql語句隊列,一般用于遠程提交數(shù)據(jù),每次插入一條執(zhí)行多條。
- 支持批量sql語句隊列,一般用于批量更新數(shù)據(jù),每次插入多條執(zhí)行多條。
- 可設(shè)置隊列最大數(shù)量,限定排隊處理的sql語句集合。
- 通過信號發(fā)出 打印信息、錯誤信息、查詢結(jié)果。
(三)數(shù)據(jù)庫通用翻頁類
- 可設(shè)置每頁多少行記錄,自動按照設(shè)定的值進行分頁。
- 可設(shè)置要查詢的表名、字段集合、條件語句、排序語句。
- 可設(shè)置第一頁、上一頁、下一頁、末一頁、翻頁按鈕。
- 可設(shè)置當前頁、總頁數(shù)、總記錄數(shù)、每頁記錄數(shù)、查詢用時標簽頁。
- 多線程查詢總記錄數(shù),數(shù)據(jù)量巨大時候不會卡主界面。
- 建議條件字段用整型類型的主鍵,速度極快。
- 提供查詢結(jié)果返回信號,包括當前頁、總頁數(shù)、總記錄數(shù)、查詢用時等信息。
- 可設(shè)置所有列或者某一列對齊樣式例如居中或者右對齊。
- 可增加列用于標識該條記錄,設(shè)定列的位置、標題、寬度。
- 提供函數(shù)直接執(zhí)行第一頁、上一頁、下一頁、末一頁。
- 提供函數(shù)直接跳轉(zhuǎn)到指定頁。
- 根據(jù)是否第一頁、末一頁自動禁用對應的按鈕。
- 本控件是翻頁功能類,和翻頁控件navpage完美搭配,形成超級牛逼的翻頁控件。
(四)分頁導航控件
- 可設(shè)置頁碼按鈕的個數(shù)。
- 可設(shè)置字體大小。
- 可設(shè)置邊框圓角角度、大小、顏色。
- 可設(shè)置正常狀態(tài)背景顏色、文字顏色。
- 可識別懸停狀態(tài)背景顏色、文字顏色。
- 可設(shè)置按下狀態(tài)背景顏色、文字顏色。
- 可設(shè)置選中狀態(tài)背景顏色、文字顏色。
- 可設(shè)置導航位置居中對齊、左對齊、右對齊。
- 可設(shè)置是否顯示提示標簽控件。
- 自動計算總頁碼數(shù)顯示隱藏多余按鈕。
- 自動計算切換頁碼導航。
- 和分頁導航功能類無縫對接完美融合。
(五)自動清理數(shù)據(jù)線程類
- 可設(shè)置要清理的對應數(shù)據(jù)庫連接名稱和表名。
- 可設(shè)置條件字段。
- 可設(shè)置排序字段。
- 可設(shè)置最大保留的記錄數(shù)。
- 可設(shè)置執(zhí)行自動清理的間隔。
- 后期支持多個數(shù)據(jù)庫和多個表。
- 建議條件字段用數(shù)字類型的主鍵,速度極快。
- 增加統(tǒng)計用字段名稱設(shè)置。
- 增加自動清理文件夾,超過大小自動刪除文件夾中早期文件。
(六)自定義委托全家桶
- 可設(shè)置多種委托類型,例如復選框、文本框、下拉框、日期框、微調(diào)框、進度條等。
- 可設(shè)置是否密文顯示,一般用于文本框。
- 可設(shè)置是否允許編輯,一般用于下拉框。
- 可設(shè)置是否禁用,一般用來禁用某列。
- 可設(shè)置數(shù)據(jù)集合,比如下拉框數(shù)據(jù)集合。
- 提供值變化信號,比方說下拉框值改動觸發(fā)。
- 可設(shè)置數(shù)據(jù)校驗自動產(chǎn)生不同的圖標。
- 支持設(shè)置校驗列、校驗規(guī)則、校驗值、校驗成功圖標、校驗失敗圖標、圖標大小。
- 可設(shè)置校驗數(shù)據(jù)產(chǎn)生不同的背景顏色和文字顏色。
- 校驗規(guī)則支持 == > >= < <= != contains,非常豐富。
- 復選框自動居中而不是左側(cè),切換選中狀態(tài)發(fā)送對應的信號。
- 可設(shè)置顏色委托,自動根據(jù)顏色值繪制背景顏色,自動設(shè)置最佳文本顏色。
- 可設(shè)置按鈕委托,自動根據(jù)值生成多個按鈕,按鈕按下發(fā)送對應的信號。
- 當設(shè)置了委托列時自動繪制選中背景色和文字顏色。
- 可設(shè)置關(guān)鍵字對照表繪制關(guān)鍵字比如原始數(shù)據(jù)是 0-禁用 1-啟用。
- 可設(shè)置復選框?qū)挠成溥x中不選中關(guān)鍵字。
- 根據(jù)不同的委托類型繪制,可以依葫蘆畫瓢自行增加自己的委托。
- 所有功能封裝成1個類,核心代碼不到500行,使用極其方便友好。
(七)效果圖







(八)體驗地址
體驗地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg 提取碼:uyes 文件名:bin_dbtool.zip
國內(nèi)站點:https://gitee.com/feiyangqingyun
國際站點:https://github.com/feiyangqingyun
以上就是Qt數(shù)據(jù)庫相關(guān)應用開發(fā)總結(jié)的詳細內(nèi)容,更多關(guān)于Qt數(shù)據(jù)庫開發(fā)的資料請關(guān)注腳本之家其它相關(guān)文章!
- Qt數(shù)據(jù)庫應用之實現(xiàn)通用數(shù)據(jù)生成器
- Qt數(shù)據(jù)庫應用之實現(xiàn)數(shù)據(jù)圖文混排
- Qt數(shù)據(jù)庫應用之實現(xiàn)數(shù)據(jù)打印到紙張
- Qt數(shù)據(jù)庫應用之數(shù)據(jù)打印到pdf
- Qt數(shù)據(jù)庫應用之實現(xiàn)數(shù)據(jù)的導入與導出
- C/C++ Qt 數(shù)據(jù)庫與Chart歷史數(shù)據(jù)展示
- C/C++?Qt數(shù)據(jù)庫SqlRelationalTable關(guān)聯(lián)表詳解
- C/C++?Qt數(shù)據(jù)庫與SqlTableModel組件應用教程
相關(guān)文章
FFmpeg實現(xiàn)將編碼后數(shù)據(jù)保存成mp4
這篇文章主要為大家詳細介紹了FFmpeg如何實現(xiàn)將編碼后數(shù)據(jù)保存成mp4,即從內(nèi)存塊中獲取原始數(shù)據(jù),然后依次進行解碼、編碼、最后保存成mp4視頻文件,感興趣的可以了解一下2023-08-08
VSCode插件開發(fā)全攻略之package.json詳解
這篇文章主要介紹了VSCode插件開發(fā)全攻略之package.json的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
淺談C++的語句語法與強制數(shù)據(jù)類型轉(zhuǎn)換
這篇文章主要介紹了淺談C++的語句語法與強制數(shù)據(jù)類型轉(zhuǎn)換,是C++入門學習中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09
C++構(gòu)造函數(shù)+復制構(gòu)造函數(shù)+重載等號運算符調(diào)用
這篇文章主要介紹了C++構(gòu)造函數(shù)+復制構(gòu)造函數(shù)+重載等號運算符調(diào)用,文章敘述詳細,具有一定的的參考價值,需要的小伙伴可以參考一下2022-03-03

