QT——入門之數據庫(2)

這一節,我講一下數據庫怎麼在QT中使用。我這裏是以單例模式使用。

代碼書寫

步驟1:
首先,我們在建立好一個工程後,我們要在pro文件中加上sql模塊
在這裏插入圖片描述
步驟2:建立一個無繼承關係的類CSDB,寫入一下代碼
CSDB.h文件

#include <QtSql>
#include <QSqlDatabase>     //用於創建sql數據庫
#include <QSqlError>        //提示sql數據庫操作時錯誤
#include <QSqlQuery>        //提供數據庫的 操作方法
#include <QDebug>

class CSDB
{
public:
    ~CSDB();
    static CSDB *GetCSDB(const QString &filename);
    bool CreateTable(QString TableName,QString Code);	//建立表格的函數
private:
    CSDB(const QString &filename);  //打開一個 某個數據庫
    static CSDB * pcsdb;         //數據庫指針,這裏設置成靜態主要爲了記錄有沒有建立好了數據庫
    QSqlDatabase database;       //數據庫
};

這裏解析一下單例模式,我們在項目中就只需要一個數據庫,所以每次我們要用到數據庫的時候,不是說用一次建一個,而是建立一個數據庫,下次要用的時候我就調用第一次建立的那個數據庫。
注意:這裏我的這個構造函數是放在私有之中,公共區只有一個獲取數據庫的方法。

步驟3、完善代碼,CSDB.cpp文件

#include "csdb.h"
CSDB *CSDB::pcsdb = NULL;	//靜態變量pcsdb要在類外定義
//構造函數
CSDB::CSDB(const QString &filename)	//傳入數據庫名稱來獲取數據庫,注意要有後綴db
{
    qDebug() << "CSDB Create" ;
    //防止出現“可能會存在隱式內存泄漏”的警告
    if(QSqlDatabase::contains("qt_sql_default_connection"))
    {
        database = QSqlDatabase::database("qt_sql_default_connection");
    }
    else
    {
        //選擇數據庫的類型並且創立
        this->database = QSqlDatabase::addDatabase("QSQLITE");      
    }
    //設置數據庫的名字,注意要有後綴db
    this->database.setDatabaseName(filename);
    //打開數據庫,打印是否打開成功                   
    if(!this->database.open())
    {
        qDebug() << "數據庫打開失敗" ;
    }
    else
    {
        qDebug() << "數據庫打開成功" ;
    }
    
    //玩家名字、分數
    QString TableName_UserData = "UserData";
    QString UserData_Code = "userName text ,scores integer";
    
    //這裏CreateTable函數是自己寫的	
    this->CreateTable(TableName_UserData,UserData_Code);
} 
//建立表格函數
bool CSDB::CreateTable(QString TableName,QString Code)
{
    //這裏使用的是QString 類當中的一個字符串拼接的函數,arg口號裏面填寫前面%1、%2處的地方
    QString create_sql = QString("create table if not exists %1(%2);").arg(TableName).arg(Code);
    
    //建立一個操作對象來執行數據庫的代碼
    QSqlQuery SqlQuery;
    //把代碼放到執行器中     
    SqlQuery.prepare(create_sql);
    //判斷是否執行成功,並且打印是否成功
    if(!SqlQuery.exec(create_sql))
    {        
        qDebug()<<"失敗";
        return 0;
    }
    else
    {       
    	qDebug()<<"建表成功";
        return 1;
    }
}
//獲取數據庫
CSDB * CSDB::GetCSDB(const QString &filename)
{
    //判斷有沒有數據庫?如果不存在就創建,注意這裏我的pcsdb是靜態變量
    if(NULL == pcsdb)
    {
    	//創建數據庫
        pcsdb= new CSDB(filename);
    }
    //注意我這裏返回的是一個數據庫指針
    return pcsdb;
}
//析構函數,關閉數據庫
CSDB::~CSDB()
{
    //關閉數據庫
    database.close();
    qDebug() << "數據庫以正常關閉" ;
}

步驟4、其他類對數據庫的調用

//頭文件
#include "csdb.h"
#include <QLabel>       //標籤
class Rank: public QWidget
{
    Q_OBJECT
public:
    explicit Rank(QWidget *parent = 0);
    void RankShow();
    
    //建立一些標籤來顯示數據庫查詢到的東西
    QLabel *label_Num[10];
    QLabel *label_Name[10];
    QLabel *label_Scores[10];
private:
    CSDB * my_csdb;
}

//cpp文件
Rank::Rank(QWidget *parent)
    : QWidget(parent)
{ 
    //打開數據
    my_csdb = CSDB::GetCSDB("My_GameData.db");
    
    //設置一下標籤的位置 
    int i;
    for(i = 0; i < 10; i++)
    {
        label_Num[i] = new QLabel(this);
        label_Name[i] = new QLabel(this);
        label_Scores[i] = new QLabel(this);

        label_Num[i]->setGeometry(QRect(50, 180+i*40, 60, 21));
        label_Name[i]->setGeometry(QRect(170, 180+i*40, 120, 21));
        label_Scores[i]->setGeometry(QRect(360, 180+i*40, 60, 21));
        
        label_Num[i]->setStyleSheet("QLabel{font:bold;color:rgb(94,200,255) ;font-size:18px;}");
        label_Name[i]->setStyleSheet("QLabel{font:bold;color:rgb(94,200,255) ;font-size:18px;}");
        label_Scores[i]->setStyleSheet("QLabel{font:bold;color:rgb(94,200,255) ;font-size:18px;}");
        
	this->RankShow();
    }
}

void Rank::RankShow()
{
    //查詢My_GameData數據庫的UserData表格中降序的scores字段 
    QString insert_sql = "select * from UserData order by scores DESC;";
    //建立SQL數據庫的執行器
    QSqlQuery sqlquery;
    //用執行器執行代碼,看是否能編譯過去
    if(!sqlquery.exec(insert_sql))
    {
    	//編譯過程出錯,輸出錯誤
        qDebug() << "register  fail" << sqlquery.lastError() ;
        //return 0;
    }
    else
    {
    	//RankNum來標記數據的序號,row來表示函數
    	int RankNum = 1;
        int row = 0;
        while(sqlquery.next())  //提取查詢到的信息
        {
            if(row<=9)
            {
                label_Num[row]->setText(QString("%1").arg(RankNum));
                label_Name[row]->setText(sqlquery.value(0).toString());
                label_Scores[row]->setText(sqlquery.value(1).toString());
                row++;
            }
            RankNum++;  //計算總共有幾條
      }
    }
}

相關思路

我在項目中使用數據庫的話,一般是在一個程序開始的時候就打開數據庫(就是說我在項目中只使用到一次CSDB::GetCSDB(“My_GameData.db”);),並沒有說要用是的時候打開,不用就關閉,如果你在很多類當中都要用到數據,那麼你隨意delete數據庫指針很容易造成內存泄漏!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章