记录一下QSqlDatabase数据库的单例类

用于存界面一个数据库表,目前只有一个数据库存了一个IP地址

QSqlDatabase类的sqlite数据库在Qt的项目工程里反复使用,使用单例加禁止拷贝构造,加互斥锁保证线程安全

头文件

#ifndef SQLITEDB_H
#define SQLITEDB_H

#include <QObject>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDir>
#include <QApplication>
#include <QDebug>
#include <QMutex>
#include <QMutexLocker>



/* "OvenIPTable" (Id INTEGER PRIMARY KEY AUTOINCREMENT,OvenIP TEXT NOT NULL); // Id一直为1*/


class sqliteDB : public QObject
{
    Q_OBJECT
public:
    static sqliteDB* getInstance();
    QSqlDatabase& getDatabase();
    bool initDB();

    bool createSettingConfigTable();  //创建设置配置表
    QString getOvenIPAddress();       //获取设置配置
    bool updateOvenIPAddress(QString IPAddress);//更新设置配置表

signals:
    void sig_logInfo(QString info);

private :
    sqliteDB();
    ~sqliteDB();

    sqliteDB(const sqliteDB&) = delete; //禁止拷贝构造
    sqliteDB& operator=(const sqliteDB&) = delete; //禁止赋值操作

    static sqliteDB* instance;
    QMutex mutex;
    QSqlDatabase db;

    QString m_sDBName;
    QString m_sDBPath;
};

#endif // SQLITEDB_H

实现

#include "sqliteDB.h"

// 静态成员初始化
sqliteDB* sqliteDB::instance = nullptr;

sqliteDB::sqliteDB()
    : QObject(), db(QSqlDatabase::addDatabase("QSQLITE", "OvenIPTable"))
{
    m_sDBName = "entryStation.db";
    m_sDBPath = QDir::currentPath()+"/res/db";
    if(initDB())
    {
        qDebug() << "OvenIPTable数据库连接成功";
    }
}

sqliteDB::~sqliteDB()
{

}

sqliteDB* sqliteDB::getInstance()
{
    if(!instance)
    {
        instance = new sqliteDB();
    }
    return instance;
}

QSqlDatabase& sqliteDB::getDatabase()
{
    if(!db.isOpen())
    {
        if(!initDB())
        {
            qWarning()<<"Database not initialized or cannot be opened ";
        }
    }
    return db;
}

bool sqliteDB::initDB()
{
    QDir db_dir;
    if(!db_dir.exists(m_sDBPath))
    {
        bool success = db_dir.mkpath(m_sDBPath);
        if(success)
        {
            qDebug()<<"创建路径成功!";
        }else
        {
            qWarning()<<"创建路径失败!";
            return false;
        }
    }
    QString dir = m_sDBPath+"/"+m_sDBName;

    qDebug() << dir;

    //db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(dir);
    if(!db.open())
    {
        qWarning()<<"数据库打开失败";
        return false;
    }
        qDebug() << "__________XXXXX";
    // 创建表(如果尚未存在)
    if ( !createSettingConfigTable()) {
        return false;
    }

    return true;
}

//创建设置配置表,只需要主机的IP
bool sqliteDB::createSettingConfigTable()
{
    QMutexLocker locker(&mutex);
    if(!db.isOpen())
    {
        return false;
    }
    bool createRet = false;
    if(db.tables().contains("OvenIPTable"))
    {
        createRet = true;
    }
    else
    {
        QSqlQuery query(db);
        QString str_createSql = QString("create table if not exists OvenIPTable ( \
                                        Id INTEGER PRIMARY KEY AUTOINCREMENT,\
                                        OvenIP TEXT NOT NULL)");
            createRet = query.exec(str_createSql);
        if(!createRet)
        {
            qWarning()<<"创建IP配置表失败!"<<query.lastError().text();
        }
        else
        {
            //第一次创建,默认存储主机连接的IP
            QString str_insertSql = QString("insert into OvenIPTable values(1,'192.168.155.200')");
            if(!query.exec(str_insertSql))
            {
                qWarning()<<"Insert default setting Error="<<query.lastError().text();
            }
        }
    }
    return createRet;
}

//获取设置配置
QString sqliteDB::getOvenIPAddress()
{
    QMutexLocker locker(&mutex);

    QString IPAddress;//返回的主机IP地址
    if(!db.isOpen())
    {
        return "";
    }
    QSqlQuery query(db);
    QString str_selectSql = QString("select OvenIP from OvenIPTable where Id = 1;");
    if(query.exec(str_selectSql))
    {
        while (query.next())
        {
            IPAddress = query.value(0).toString()  ;
        }

    }
    return IPAddress;
}

//更新表主机IP
bool sqliteDB::updateOvenIPAddress(QString IPAddress)
{
    QMutexLocker locker(&mutex);
    if(!db.isOpen())
    {
        return false;
    }

    QSqlQuery query(db);
    QString str_selectSql = QString("REPLACE INTO OvenIPTable(Id,OvenIP) VALUES(1,'%1');").arg(IPAddress);
    if(!query.exec(str_selectSql))
    {
        qWarning()<<"update ip_config error"<<query.lastError().text();
        emit sig_logInfo("保存IP设置失败!");
        return false;
    }
    return true;
}

Qt(一种跨平台的C++应用程序框架)结合Linux环境下的应用中,利用数据库单例模式处理多进程通信通常涉及以下几个步骤: 1. **数据库单例模式**:单例模式在这里用于确保在整个程序中只有一个数据库连接实例。这有助于管理资源,避免每个进程创建单独的数据库连接,尤其是在多线程或多进程中。 ```cpp class DatabaseManager : public QObject { public: static DatabaseManager* getInstance(); QSqlDatabase getDatabase(); private: DatabaseManager(); // 防止外部直接构造 ~DatabaseManager(); //析构函数私有,防止销毁多次 QSqlDatabase m_database; }; ``` 2. **进程间通信(IPC)**:为了在多个进程中共享这个单例实例,可以使用Unix/Linux特有的信号量、互斥锁(mutex)或者无主文件系统(如FIFO管道、D-Bus等)。例如,通过传递一个标识符或者锁文件来同步对单例的访问。 3. **多进程操作**:在启动新进程中,检查是否需要建立数据库连接。如果是第一次访问或已经获取到有效的单例,则使用该实例;否则,在获取权限后创建新的数据库连接,并更新单例。 4. **线程安全**:由于Qt是线程安全的,所以使用QMutex保证数据库实例在多线程环境下的安全性。 **相关问题--:** 1. 在Qt中如何保证单例模式在多进程间的唯一性? 2. 如何使用Qt的信号槽机制协调不同进程中对数据库的操作? 3. 使用数据库单例模式在处理大量并发请求时有哪些潜在问题需要注意?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄猿欲度愁攀援

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值