1. 程式人生 > >Qt操作多個Sqlite資料庫和檔案讀寫

Qt操作多個Sqlite資料庫和檔案讀寫

摘要:

    Qt自帶了sqlite的驅動,也有各種檔案的讀寫操作,用起來很是方便,這裡僅僅是做了一個簡單的封裝,方便多個數據庫和多個檔案的操作。
    用到這塊的時候網上搜了很多參考資料,感謝大家的無私分享,這裡把搜後整理的結果分享給大家,對無私分享的廣大碼農表示感謝!!!如有需要可隨意轉載與貼上。
    在此封裝了一個datacontrol類,來控制多個數據庫和檔案的操作。
    需要加以說明的是:
    1)sqlite的事務機制,正常情況下執行sql語句,會出現頻繁的資料庫讀寫操作,啟用事務機制後,會在一定狀態下去執行資料庫的讀寫,相當於記憶體裡面有一個緩衝池,會提高n倍的資料庫操作效率。
    2)如何以指標的形式儲存QSqlDatabase
    3)對sqlite採用開啟資料庫採用不同的連線名稱,為什麼要採用不同的連結名稱?這就是同時操作多個sqlite資料庫的答案。
    4)檔案的讀寫,這裡做的比較簡單,資料庫的讀寫也很簡單,沒有對sql語句的執行進行封裝,有興趣的朋友可以繼續完善。
    宣告:此處沒有任何創新,都來自於物聯網   【碼友】    的貢獻。

程式碼

不多說廢話了,貼上程式碼。
先是標頭檔案

#ifndef _DATA_CONTROL_H_
#define _DATA_CONTROL_H_

#include <QtSql/qsqldatabase.h>
#include <QtSql/qsqlquery.h>
#include <QtSql/qsqlerror>
#include <qstring>
#include <QtCore/qstringlist>
#include <QFile>
#include <QtCore/qmap.h>
//資料操作類 //使用QMap實現一個簡單的鎖 namespace QTOOL { class DataControl { public: DataControl(); ~DataControl(); //開啟、關閉資料庫 QSqlDatabase* OpenDataBase(QString strDataBase); bool CloseDataBase(QString strDataBase); QSqlDatabase* FindDataBase(QString strDataBase); QSqlDatabase* FlushDataBase(QString strDataBase); //開啟、關閉檔案
QFile* OpenFile(QString strFile,QFlags<QIODevice::OpenModeFlag> eOpenMode = QIODevice::Append); bool CloseFile(QString strFile); QFile* FindFile(QString strFile); //bool public: QMap<QString,QSqlDatabase*> m_mapDataBase; QMap<QString,QFile*> m_mapFile; }; } ////////////////////////////////////////////////////////////////////////// //================================寫檔案示例============================== //QTOOL::DataControl dc; //QFile* file = dc.OpenFile(QString::fromLocal8Bit("d:/test.ini")); //if (file != NULL) //{ // QTextStream ts(&*file); // for (int i = 0; i < 10;i++) // { // ts<<"hello " << i << "\n"; // } // file->flush(); // file->close(); //} ////////////////////////////////////////////////////////////////////////// //============================讀檔案示例================================== //QTOOL::DataControl dc; // //QString fileAddress = QString::fromLocal8Bit("d:/test.ini"); //QFile* file = dc.OpenFile(fileAddress,QIODevice::ReadOnly); //QTextStream ts(file); // //QString fileDate = ts.readLine(); //QString dataBaseStruct = ts.readLine(); //while(!ts.atEnd()) //{ // a++; // QString strCurrentLine = ts.readLine(); // QStringList strListCurrentLine = strCurrentLine.split(";"); // //} //dc.CloseFile(fileAddress); ////////////////////////////////////////////////////////////////////////// //======================讀資料庫並寫入檔案示例============================ //QTOOL::DataControl dc; // //QString fileAddress = QString::fromLocal8Bit("d:/test2.ini"); //QFile* file = dc.OpenFile(fileAddress,QIODevice::ReadWrite|QIODevice::Truncate); //QTextStream ts(file); // ////ts<<"ID;BELONG;NAME;STATE;LON;LAT;PIC\n"; // //QString fileDate = ts.readLine(); //QString dataBaseStruct = ts.readLine(); // ////開啟資料庫 //QString strDataBaseAddress = QString::fromLocal8Bit("d:/test.db"); //QSqlDatabase* database = dc.OpenDataBase(strDataBaseAddress); //QString create_sql = "create table student (id int ,belong varchar(100), name varchar(100),state int,lon float,lat float,pic varchar(200))"; //QString insert_sql = "insert into student values (?, ?, ?, ? ,? ,? ,?)"; //QString select_all_sql = "select * from student"; ////QSqlQuery類提供執行和操作的SQL語句的方法。 ////可以用來執行DML(資料操作語言)語句,如SELECT、INSERT、UPDATE、DELETE, ////以及DDL(資料定義語言)語句,例如CREATE TABLE。 ////也可以用來執行那些不是標準的SQL的資料庫特定的命令。 //QSqlQuery sql_query(*database); //sql_query.prepare(select_all_sql); // //if (sql_query.exec()) //{ // while(sql_query.next()) // { // ts<<sql_query.value(0).toString()<<";"<<sql_query.value(1).toString()<<";" // <<sql_query.value(2).toString()<<";"<<sql_query.value(3).toString()<<";" // <<sql_query.value(4).toString()<<";"<<sql_query.value(5).toString()<<";" // <<sql_query.value(6).toString()<<"\n"; // // } //} // //dc.FlushDataBase(strDataBaseAddress); //dc.CloseFile(fileAddress); //dc.CloseDataBase(strDataBaseAddress); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //=======================讀檔案並寫入資料庫示例=========================== //QTOOL::DataControl dc; // //QString fileAddress = QString::fromLocal8Bit("d:/test.ini"); //QFile* file = dc.OpenFile(fileAddress,QIODevice::ReadOnly); //QTextStream ts(file); // ////ts<<"ID;BELONG;NAME;STATE;LON;LAT;PIC\n"; // //QString fileDate = ts.readLine(); //QString dataBaseStruct = ts.readLine(); // ////開啟資料庫 //QString strDataBaseAddress = QString::fromLocal8Bit("d:/test.db"); //QSqlDatabase* database = dc.OpenDataBase(strDataBaseAddress); //QString create_sql = "create table student (id int ,belong varchar(100), name varchar(100),state int,lon float,lat float,pic varchar(200))"; //QString insert_sql = "insert into student values (?, ?, ?, ? ,? ,? ,?)"; // ////QSqlQuery類提供執行和操作的SQL語句的方法。 ////可以用來執行DML(資料操作語言)語句,如SELECT、INSERT、UPDATE、DELETE, ////以及DDL(資料定義語言)語句,例如CREATE TABLE。 ////也可以用來執行那些不是標準的SQL的資料庫特定的命令。 //QSqlQuery sql_query(*database); //sql_query.prepare(create_sql); //if(!sql_query.exec()) //{ // qDebug()<<sql_query.lastError(); //} //else //{ // qDebug()<<"table created!"; //} // //int a = 0; // //while(!ts.atEnd()) //{ // a++; // QString strCurrentLine = ts.readLine(); // QStringList strListCurrentLine = strCurrentLine.split(";"); // // // strListCurrentLine.at(0); // sql_query.prepare(insert_sql); // sql_query.addBindValue(strListCurrentLine.at(0).toInt()); // sql_query.addBindValue(strListCurrentLine.at(1)); // sql_query.addBindValue(strListCurrentLine.at(2)); // sql_query.addBindValue(strListCurrentLine.at(3).toInt()); // sql_query.addBindValue(strListCurrentLine.at(4).toFloat()); // sql_query.addBindValue(strListCurrentLine.at(5).toFloat()); // sql_query.addBindValue(strListCurrentLine.at(6)); // // if(!sql_query.exec()) // { // qDebug()<<sql_query.lastError(); // } // else // { // qDebug()<<"inserted!"; // } //} //dc.FlushDataBase(strDataBaseAddress); // //dc.CloseFile(fileAddress); //dc.CloseDataBase(strDataBaseAddress); ////////////////////////////////////////////////////////////////////////// #endif

cpp檔案

#include "DataControl.h"


QTOOL::DataControl::DataControl()
{

}

QTOOL::DataControl::~DataControl()
{
    //對沒有關閉的資料庫進行關閉
    if (m_mapDataBase.count() > 0)
    {
        QMap<QString,QSqlDatabase*>::iterator it = m_mapDataBase.begin();
        if (it != m_mapDataBase.end())
        {
            if (it.value()->isOpen())
            {
                it.value()->close();
            }
        }
        m_mapDataBase.clear();
    }

    //對沒有關閉的檔案進行關閉
    if (m_mapFile.count() > 0)
    {
        QMap<QString,QFile*>::iterator it2 = m_mapFile.begin();
        if (it2 != m_mapFile.end())
        {
            if (it2.value()->isOpen())
            {
                it2.value()->close();
            }
        }
        m_mapFile.clear();
    }
}

QSqlDatabase* QTOOL::DataControl::OpenDataBase( QString strDataBase )
{
    QMap<QString,QSqlDatabase*>::iterator it = m_mapDataBase.find(strDataBase);
    if (it != m_mapDataBase.end())
    {
        //判斷資料庫庫是否已經被關閉
        if (!m_mapDataBase[strDataBase]->isOpen())
        {
            m_mapDataBase[strDataBase]->open();
        }
        //開啟一個事務,使用事務批量寫入SQLite的速度會有很大的提高。
        m_mapDataBase[strDataBase]->transaction();
        return (m_mapDataBase[strDataBase]);
    }

    //注意:這裡使用檔案地址作為連結名稱,否則開啟多個數據庫,先開啟的會被後開啟的覆蓋。
    QSqlDatabase* database= new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE",strDataBase));

    database->setDatabaseName(strDataBase);
    database->setUserName("root123");  
    database->setPassword("123456");

    //開啟資料庫
    if(!database->open())
    {
        return NULL;
    }

    m_mapDataBase.insert(strDataBase,database);

    m_mapDataBase[strDataBase]->transaction();
    return m_mapDataBase[strDataBase];
}

bool QTOOL::DataControl::CloseDataBase( QString strDataBase )
{
    QMap<QString,QSqlDatabase*>::iterator it = m_mapDataBase.find(strDataBase);

    if (it != m_mapDataBase.end())
    {
        //關閉檔案
        //先結束事務(不結束應該也沒什麼影響,關閉會自動重新整理的)
        it.value()->commit();
        it.value()->close();
        //從列表裡面刪除
        m_mapDataBase.erase(it);
        return true;
    }
    return false;
}

QSqlDatabase* QTOOL::DataControl::FindDataBase( QString strDataBase )
{
    QMap<QString,QSqlDatabase*>::iterator it = m_mapDataBase.find(strDataBase);
    if (it != m_mapDataBase.end())
    {
        return (it.value());
    }
    return NULL;
}

QSqlDatabase* QTOOL::DataControl::FlushDataBase( QString strDataBase )
{
    QMap<QString,QSqlDatabase*>::iterator it = m_mapDataBase.find(strDataBase);
    if (it != m_mapDataBase.end())
    {
        //提交上一個事務,並開始一個新的事務
        it.value()->commit();
        it.value()->transaction();
        return (it.value());
    }
    return NULL;
}


QFile* QTOOL::DataControl::OpenFile( QString strFile, QFlags<QIODevice::OpenModeFlag> eOpenMode)
{
    QMap<QString,QFile*>::iterator it = m_mapFile.find(strFile);
    if (it != m_mapFile.end())
    {
        //判斷檔案是否已經被關閉
        if (!m_mapFile[strFile]->isOpen())
        {
            m_mapFile[strFile]->open(eOpenMode);
        }
        return (m_mapFile[strFile]);
    }
    QFile* file = new QFile(strFile);

    if (file->open(eOpenMode))
    {
        m_mapFile.insert(strFile,file);
        return (m_mapFile[strFile]);
    }
    return NULL;
}

bool QTOOL::DataControl::CloseFile( QString strFile )
{
    QMap<QString,QFile*>::iterator it = m_mapFile.find(strFile);
    if (it != m_mapFile.end())
    {
        //關閉檔案
        it.value()->close();
        //從列表裡面刪除
        m_mapFile.erase(it);
        return true;
    }
    return false;
}

QFile* QTOOL::DataControl::FindFile( QString strFile )
{
    QMap<QString,QFile*>::iterator it = m_mapFile.find(strFile);
    if (it != m_mapFile.end())
    {
        return (it.value());
    }
    return NULL;
}

有任何疑問或錯漏之處歡迎批評指正!

&&我是程式碼的搬運工&&