Qt5.x-鏈接Sqlite

前言

完成Qt的基礎(chǔ)語法學(xué)習(xí)后烙丛,嘗試跟著教程完成了翻金幣小游戲憎账,但在實際使用Qt的過程中趴捅,會遇到保存數(shù)據(jù)的需求垫毙,經(jīng)過查找,確定使用SQLite數(shù)據(jù)庫作為練習(xí)數(shù)據(jù)庫拱绑,SQLite版本選擇的是版本SQLite3.0

目標(biāo)

1.鏈接SQLite3.0數(shù)據(jù)庫综芥,完成初始化鏈接,測試如果首次鏈接完成后猎拨,第二次啟動程序如何與現(xiàn)有數(shù)據(jù)庫鏈接膀藐;
2.鏈接完成初始化數(shù)據(jù)庫,完成基礎(chǔ)表的創(chuàng)建和數(shù)據(jù)插入红省,完成一個登陸功能的數(shù)據(jù)初始化工作额各;
3.對數(shù)據(jù)庫使用工具進行封裝,提供工具包完成日常數(shù)據(jù)庫訪問的操作吧恃;
4.使用工具類提供的方法完成登陸按鈕點擊后的操作虾啦。

鏈接數(shù)據(jù)庫

  • 根據(jù)Qt的幫助文檔,Qt自帶SQL的操作,但是在使用SQL前需要在*.pro文件中添加QT += sql
//一個contains判斷傲醉,如果之前建立了連接蝇闭,我們就獲取連接到的數(shù)據(jù)庫,如果沒有建立連接硬毕,我們就新建一個數(shù)據(jù)庫
   m_db=QSqlDatabase::contains("qt_sql_default_connection")?   QSqlDatabase::database("qt_sql_default_connection"):QSqlDatabase::addDatabase("QSQLITE", "qt_sql_default_connection");
   m_db.setDatabaseName("strConn");
   m_db.setUserName("admin");
   m_db.setPassword("123456");
   //打開數(shù)據(jù)庫
   if (!m_db.open())
  {
       qDebug() << "Open database failed!";
       return false;
  }
   else
  {
       return true;
  }

三目運算僅是出于代碼的邏輯性編寫呻引,先判斷是否有鏈接然后直接設(shè)置和新建設(shè)置,也可以直接使用QSqlDatabase::addDatabase("QSQLITE");

如果想選用現(xiàn)有數(shù)據(jù)庫文件吐咳,經(jīng)過我自己的實驗逻悠,有兩種方法:

  • m_db.setDatabaseName("strConn");中,參數(shù)填寫的絕對路徑韭脊;
  • 需要進行文件選擇操作童谒,完成Qt的文件選擇功能,然后選擇現(xiàn)有數(shù)據(jù)庫文件乾蓬,通過QFile復(fù)制一份到程序位置惠啄,然后返回絕對路徑填寫至m_db.setDatabaseName("strConn");中

是否有更好的處理方法慎恒,暫時沒有想到任内,由于只設(shè)計一個登陸功能,所以使用Qt中直接創(chuàng)建數(shù)據(jù)庫文件融柬,生成數(shù)據(jù)庫表和數(shù)據(jù)的方式死嗦。

生成默認表和數(shù)據(jù)

//判定是否需要進行初始化base_config和base_user兩張表
   int isInitFlag = ExecuteInt(QString ("select count(*) from sqlite_master where type='table' and name = 'base_config'"));
   if(isInitFlag == 0)
  {
       QString user_createStr = QString("create table base_user(id INTEGER PRIMARY KEY AUTOINCREMENT ,username varchar(20),password varchar(20))");
       QString user_insertStr = QString("insert into base_user values %1").arg("(NULL, 'admin', 'admin')");
       ExecuteString(user_createStr);
       ExecuteString(user_insertStr);
  }
   return true;
  • 一個登陸功能,需要的就是一張用戶表粒氧,有用戶名和密碼兩個字斷越除;
  • 按照程序邏輯的健壯性,先進行數(shù)據(jù)庫查詢是否已經(jīng)創(chuàng)建了本表外盯,如果有表則不進行表的創(chuàng)建直接返回摘盆;
  • 如果沒有用戶表,在進行用戶表創(chuàng)建后饱苟,直接向表中插入一條用戶數(shù)據(jù)完成初始化的工作孩擂;

封裝日常使用Qt與SQLlie3進行交互的工具類

  • 把創(chuàng)建數(shù)據(jù)庫鏈接和完成數(shù)據(jù)初始化的工作都放到工具類的初始化方法;
  • 創(chuàng)建數(shù)據(jù)庫鏈接和完成數(shù)據(jù)初始化都有已有文件和數(shù)據(jù)庫表的校驗
  • 在Qt提供的數(shù)據(jù)庫操作上多進行了一層封裝,可在登陸功能時直接使用
  • DbUtilBySqlite3.h
#ifndef DBUTILBYSQLITE3_H
#define DBUTILBYSQLITE3_H
?
#include <QObject>
#include <QSqlDatabase>
#include <QSqlQueryModel>
?
class DbUtilBySqlite3 : public QObject
{
   Q_OBJECT
public:
   explicit DbUtilBySqlite3(const QString& strDatabase = "smart.db");
   ~DbUtilBySqlite3();
?
   //數(shù)據(jù)庫鏈接信息
   bool createConnection(const QString& strConn);
   //初始化所需的數(shù)據(jù)表
   //base_config 初始化配置表
   //base_user 用戶表
   bool init_table_data();
?
   QSqlRecord ExecuteRecord(const QString& strQuery);
   QSqlRecord ExecuteRecord(const QString& strQuery, QList<QVariant> lstParameter);
   QSqlRecord ExecuteRecord(const QString& strQuery, QVariant Parameter);
?
   QSqlQuery ExecuteSqlQuery(const QString& strQuery, QList<QVariant> lstParameter);
   QSqlQuery ExecuteSqlQuery(const QString& strQuery, QVariant Parameter);
   QSqlQuery ExecuteSqlQuery(const QString& strQuery);
?
   int ExecuteInt(const QString& strQuery);
   int ExecuteInt(const QString& strQuery, QList<QVariant> lstParameter);
   int ExecuteInt(const QString& strQuery, QVariant Parameter);
?
   bool Execute(const QString& strQuery, QVariant Parameter);
   bool Execute(const QString& strQuery, QList<QVariant> lstParameter);
?
   QString ExecuteString(const QString& strQuery);
?
   void ExecuteQueryModel(QSqlQueryModel *p_queryModel, const QString& strQuery);
   void ExecuteQueryModel(QSqlQueryModel *p_queryModel, const QString& strQuery,
                          QList<QVariant> lstParameter);
   void ExecuteQueryModel(QSqlQueryModel *p_queryModel, const QString& strQuery, QVariant Parameter);
?
private:
   QSqlDatabase m_db;
   QString m_strDatabase;
?
signals:
?
};
?
#endif // DBUTILBYSQLITE3_H

?

  • DbUtilBySqlite3.cpp
#include "dbutilbysqlite3.h"
?
#include<QSqlDatabase>
#include<QSqlQuery>
#include<QSqlError>
#include<QDebug>
#include<QSqlRecord>
?
DbUtilBySqlite3::DbUtilBySqlite3(const QString &strDatabase) : m_strDatabase(strDatabase)
{
   createConnection(m_strDatabase);
   //初始化數(shù)據(jù)
   init_table_data();
}
?
//析構(gòu)函數(shù)關(guān)閉數(shù)據(jù)庫鏈接
DbUtilBySqlite3::~DbUtilBySqlite3()
{
   m_db.close();
}
?
bool DbUtilBySqlite3::createConnection(const QString &strConn)
{
   //一個contains判斷箱熬,如果之前建立了連接类垦,我們就獲取連接到的數(shù)據(jù)庫,如果沒有建立連接城须,我們就新建一個數(shù)據(jù)庫
   m_db=QSqlDatabase::contains("qt_sql_default_connection")?QSqlDatabase::database("qt_sql_default_connection")
                                                                    :QSqlDatabase::addDatabase("QSQLITE", "qt_sql_default_connection");
   m_db.setDatabaseName(strConn);
   m_db.setUserName("admin");
   m_db.setPassword("123456");
   //打開數(shù)據(jù)庫
   if (!m_db.open())
  {
       qDebug() << "Open database failed!";
       return false;
  }
   else
  {
       return true;
  }
}
?
bool DbUtilBySqlite3::init_table_data()
{
   //判定是否需要進行初始化base_user表
   int isInitFlag = ExecuteInt(QString ("select count(*) from sqlite_master where type='table' and name = 'base_config'"));
   if(isInitFlag == 0)
  {
       QString user_createStr = QString("create table base_user(id INTEGER PRIMARY KEY AUTOINCREMENT ,username varchar(20),password varchar(20))");
       QString user_insertStr = QString("insert into base_user values %1").arg("(NULL, 'admin', 'admin')");
       ExecuteString(user_createStr);
       ExecuteString(user_insertStr);
  }
   return true;
}
?
QSqlRecord DbUtilBySqlite3::ExecuteRecord(const QString& strQuery)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   query.exec();
   return query.record();
}
?
QSqlRecord DbUtilBySqlite3::ExecuteRecord(const QString& strQuery, QList<QVariant> lstParameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   for(int i = 0; i < lstParameter.count(); I++)
       query.bindValue(i, lstParameter[I]);
   query.exec();
   return query.record();
}
?
QSqlRecord DbUtilBySqlite3::ExecuteRecord(const QString& strQuery, QVariant Parameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   query.bindValue(0, Parameter);
   query.exec();
   return query.record();
}
?
QSqlQuery DbUtilBySqlite3::ExecuteSqlQuery(const QString& strQuery, QList<QVariant> lstParameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   query.setForwardOnly(true);
   for(int i = 0; i < lstParameter.count(); I++)
       query.bindValue(i, lstParameter[I]);
   query.exec();
   return query;
}
?
QSqlQuery DbUtilBySqlite3::ExecuteSqlQuery(const QString& strQuery, QVariant Parameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.setForwardOnly(true);
   query.prepare(strQuery);
   query.bindValue(0, Parameter);
   query.exec();
   return query;
}
?
QSqlQuery DbUtilBySqlite3::ExecuteSqlQuery(const QString& strQuery)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.setForwardOnly(true);
   query.prepare(strQuery);
   query.exec();
   return query;
}
?
int DbUtilBySqlite3::ExecuteInt(const QString& strQuery)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   query.exec();
   int ID = 0;
   while(query.next())
  {
       ID = query.value(0).toInt();
  }
   return ID;
}
?
int DbUtilBySqlite3::ExecuteInt(const QString& strQuery, QList<QVariant> lstParameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   for(int i = 0; i < lstParameter.count(); I++)
       query.bindValue(i, lstParameter[I]);
   query.exec();
   int ID = 0;
   while(query.next())
  {
       ID = query.value(0).toInt();
  }
   return ID;
}
?
int DbUtilBySqlite3::ExecuteInt(const QString& strQuery, QVariant Parameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   query.bindValue(0, Parameter);
   query.exec();
   int ID = 0;
   while(query.next())
  {
       ID = query.value(0).toInt();
  }
   return ID;
}
?
bool DbUtilBySqlite3::Execute(const QString& strQuery, QVariant Parameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   query.bindValue(0, Parameter);
   return query.exec();
}
?
bool DbUtilBySqlite3::Execute(const QString& strQuery, QList<QVariant> lstParameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   for(int i = 0; i < lstParameter.count(); I++)
       query.bindValue(i, lstParameter[I]);
   return query.exec();
}
?
QString DbUtilBySqlite3::ExecuteString(const QString& strQuery)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   query.exec();
   QString temp;
   while(query.next())
  {
       temp = query.value(0).toString();
  }
   return temp;
}
?
void DbUtilBySqlite3::ExecuteQueryModel(QSqlQueryModel *p_queryModel, const QString& strQuery)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   p_queryModel->setQuery(strQuery, m_db);
}
?
void DbUtilBySqlite3::ExecuteQueryModel(QSqlQueryModel *p_queryModel, const QString& strQuery,
                      QList<QVariant> lstParameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   for(int i = 0; i < lstParameter.count(); I++)
       query.bindValue(i, lstParameter[I]);
   p_queryModel->setQuery(query);
}
?
void DbUtilBySqlite3::ExecuteQueryModel(QSqlQueryModel *p_queryModel, const QString& strQuery,
                                  QVariant Parameter)
{
   if(!m_db.isOpen())
  {
       createConnection(m_strDatabase);
  }
   QSqlQuery query(m_db);
   query.prepare(strQuery);
   query.bindValue(0, Parameter);
   p_queryModel->setQuery(query);
}

登陸的信號槽

//登陸按鈕點擊
connect(ui->btn_login, &QPushButton::clicked, [=](){
 QString con_username = ui->edit_username->text();
 QString con_password = ui->edit_password->text();
 //校驗填入的參數(shù)
 if(con_username.length() <= 3 || con_password.length() <= 3)
{
   QMessageBox::critical(NULL, "填寫錯誤", "賬號或密碼太短");
}else
{
   //封裝查詢登陸
   QString str_select = QString("SELECT * FROM base_user WHERE username = ? AND password = ? AND id = 1");
   QVariant username(con_username);
   QVariant password(con_password);
   QList<QVariant> lstParameter;
   lstParameter.append(username);
   lstParameter.append(password);
?
   QSqlQuery query = dbUtil.ExecuteSqlQuery(str_select, lstParameter);
   bool loginFlag = false;
   while(query.next())
  {
     if(query.value(1).toString() == con_username && query.value(2).toString() == con_password)
    {
       loginFlag = true;
       break;
    }
  }
?
   //登陸成功跳轉(zhuǎn)到主頁面,登陸失敗進行提示
   if(loginFlag){
     this->hide();
     m = new MainWindow(this);
     m->show();
  }
   else
  {
     QApplication::setQuitOnLastWindowClosed(false);
     QMessageBox::critical(NULL, "登陸失敗", "賬號或密碼錯誤");
     QApplication::setQuitOnLastWindowClosed(true);
  }
}
});

轉(zhuǎn)載請注明轉(zhuǎn)載地址蚤认,謝謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市糕伐,隨后出現(xiàn)的幾起案子砰琢,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氯析,死亡現(xiàn)場離奇詭異亏较,居然都是意外死亡,警方通過查閱死者的電腦和手機掩缓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門雪情,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人你辣,你說我怎么就攤上這事巡通。” “怎么了舍哄?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵宴凉,是天一觀的道長。 經(jīng)常有香客問我表悬,道長弥锄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任蟆沫,我火速辦了婚禮籽暇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饭庞。我一直安慰自己戒悠,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布舟山。 她就那樣靜靜地躺著绸狐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪累盗。 梳的紋絲不亂的頭發(fā)上寒矿,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音若债,去河邊找鬼符相。 笑死,一個胖子當(dāng)著我的面吹牛拆座,可吹牛的內(nèi)容都是我干的主巍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼挪凑,長吁一口氣:“原來是場噩夢啊……” “哼孕索!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起躏碳,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤搞旭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肄渗,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡镇眷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了翎嫡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欠动。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖惑申,靈堂內(nèi)的尸體忽然破棺而出具伍,到底是詐尸還是另有隱情,我是刑警寧澤圈驼,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布人芽,位于F島的核電站,受9級特大地震影響绩脆,放射性物質(zhì)發(fā)生泄漏萤厅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一靴迫、第九天 我趴在偏房一處隱蔽的房頂上張望惕味。 院中可真熱鬧,春花似錦矢劲、人聲如沸赦拘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至阁猜,卻和暖如春丸逸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背剃袍。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工黄刚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人民效。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓憔维,卻偏偏與公主長得像,于是被迫代替她去往敵國和親畏邢。 傳聞我的和親對象是個殘疾皇子业扒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容

  • feisky云計算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,827評論 0 5
  • 念頭帶來巨大的力量舒萎,信念不正確很有可能不斷限制自己的發(fā)展程储。 信念是人對事物的看法,它是意志力的來源,和積極主動行...
    沐汐瑤閱讀 598評論 0 51
  • 浩言正語143:最美好的生活方式章鲤,不是躺在床上睡到自然醒摊灭,也不是坐在家里無所事事,更不是走在街上隨意購物败徊。而是和一...
    永遠的浩子閱讀 175評論 0 2