抽出来的,直接用就行

头文件

#ifndef DATABASECOMMON_H
#define DATABASECOMMON_H

/*
 * 单例封装SQLite通用操作,支持多线程调用;可扩展兼容其他数据库,照着SysRunDatabase写,并且重载openDatabase即可
 * 使用步骤:1、主线程addDatabase,调用setDatabase
 *         2、setDatabaseName
 *         3、按需setUserName、setPassword
 *         4、openDatabase
 *         5、查询使用execSelect,建表使用execNormalSQL,插入、修改、删除等操作使用execTransaction
 *         6、closeDatabase(程序生命周期内不需要显式调用,这里仅预留)
*/

#include <QObject>
#include <QSqlDatabase>
#include <QSqlQueryModel>
#include <QMutex>
/*
  * 类名:DatabaseCommon
  * 功能:数据库基础操作抽象类,由子类实现openDatabase操作
  * 使用方法:子类化DatabaseCommon,并实现openDatabase函数
*/
class DatabaseCommon
    : public QObject
{
    Q_OBJECT
public:
    void setDatabase(QSqlDatabase db);
    void setDatabaseName(QString dbName);
    void setUserName(QString userName);
    void setPassword(QString password);
    virtual bool openDatabase() = 0;//不同数据库的打开方式不同
    void closeDatabase();
    bool execNormalSQL(const QString &sqlString);
    bool execSelect(const QString &sqlString, QSqlQueryModel &model);
    bool execTransaction(const QString &sqlString);
    bool execTransaction(const QStringList &sqlStrings);
private:
    DatabaseCommon(const DatabaseCommon&) = delete;
    DatabaseCommon& operator=(const DatabaseCommon&) = delete;
protected:
    explicit DatabaseCommon(QObject *parent = nullptr){}
    virtual ~DatabaseCommon();
    QSqlDatabase mDatabase;
    QString mDatabaseName = "";
    QString mUserName = "";
    QString mPassword = "";
    QMutex mMutex;//保证多线程访问安全
};
/*
  * 类名:SysRunDatabase
  * 功能:应用于SysRun.db数据库,使用全局单例进行访问
*/
class SysRunDatabase : public DatabaseCommon
{
    Q_OBJECT
public:
    static SysRunDatabase& Instance()
    {
        static SysRunDatabase mInstance;
        return mInstance;
    }
    bool openDatabase() override;
protected:
    explicit SysRunDatabase(QObject *parent = nullptr){}
    ~SysRunDatabase() override {}
private:
    SysRunDatabase(const SysRunDatabase&) = delete;
    SysRunDatabase& operator=(const SysRunDatabase&) = delete;
};

#endif // DATABASECOMMON_H

CPP文件

#include "databasecommon.h"
#include <QDebug>
#include <QSqlQuery>
#include <QFile>
#include <QException>
#include <QSqlError>
#include <QMutexLocker>

DatabaseCommon::~DatabaseCommon()
{
    closeDatabase();
}
/*
 * 函数名称:setDatabase
 * 功能说明:设置数据库对象
 * 输入参数:数据库对象
 * 输出参数:无
 * 其他说明:无
 */
void DatabaseCommon::setDatabase(QSqlDatabase db)
{
    QMutexLocker locker(&mMutex);
    this->mDatabase = db;
}
/*
 * 函数名称:setDatabaseName
 * 功能说明:设置数据库名称(对于SQLite,就是db文件路径)
 * 输入参数:数据库名称
 * 输出参数:无
 * 其他说明:无
 */
void DatabaseCommon::setDatabaseName(QString dbName)
{
    QMutexLocker locker(&mMutex);
    this->mDatabaseName = dbName;
}
/*
 * 函数名称:setUserName
 * 功能说明:设置数据库用户名
 * 输入参数:用户名
 * 输出参数:无
 * 其他说明:无
 */
void DatabaseCommon::setUserName(QString userName)
{
    QMutexLocker locker(&mMutex);
    this->mUserName = userName;
}
/*
 * 函数名称:setPassword
 * 功能说明:设置数据库用户密码
 * 输入参数:用户密码
 * 输出参数:无
 * 其他说明:无
 */
void DatabaseCommon::setPassword(QString password)
{
    QMutexLocker locker(&mMutex);
    this->mPassword = password;
}
/*
 * 函数名称:openDatabase
 * 功能说明:打开数据库连接
 * 输入参数:无
 * 输出参数:无
 * 其他说明:无
 */
bool SysRunDatabase::openDatabase()
{
    QMutexLocker locker(&mMutex);
    if(!QFile::exists(mDatabaseName))
    {
        qCritical() << "not exist " << mDatabaseName;
        return false;
    }
    mDatabase.setDatabaseName(mDatabaseName);
    mDatabase.setUserName(mUserName);
    mDatabase.setPassword(mPassword);
    if(!mDatabase.open())
    {
        qCritical() << "open failed."<< mDatabase.lastError().text();
        return false;
    }
    return true;
}
/*
 * 函数名称:closeDatabase
 * 功能说明:关闭数据库连接
 * 输入参数:无
 * 输出参数:无
 * 其他说明:无
 */
void DatabaseCommon::closeDatabase()
{
    mDatabase.close();
}
/*
 * 函数名称:execNormalSQL
 * 功能说明:执行通用SQL语句(SELECT除外)
 * 输入参数:SQL语句
 * 输出参数:无
 * 其他说明:无
 */
bool DatabaseCommon::execNormalSQL(const QString &sqlString)
{
    QMutexLocker locker(&mMutex);
    if(!mDatabase.isOpen())
    {
        qCritical() << "Database is closed.";
        return false;
    }
    try
    {
        QSqlQuery query(mDatabase);
        if (!query.exec(sqlString))
        {
            throw query.lastError();
        }
        return true;
    }
    catch (const QSqlError &error)
    {
        qCritical() << "Error:" << error.text();
        return false;
    }
}
/*
 * 函数名称:execSelect
 * 功能说明:执行DQL语句(即SELECT)
 * 输入参数:SELECE语句
 * 输出参数:查询模型,获取结果
 * 其他说明:无
 */
bool DatabaseCommon::execSelect(const QString &sqlString, QSqlQueryModel &model)
{
    QMutexLocker locker(&mMutex);
    if(!mDatabase.isOpen())
    {
        qCritical() << "Database is closed.";
        return false;
    }
    if(!sqlString.startsWith("SELECT", Qt::CaseInsensitive))
    {
        qCritical() << "Unsupported operation: " << sqlString;
        return false;
    }
    try
    {
        model.setQuery(sqlString, mDatabase);
        return true;
    }
    catch (const QException &ex)
    {
        qCritical() << "Exception on model.setQuery: " << ex.what();
        qCritical() << model.lastError().text();
        return false;
    }
}
/*
 * 函数名称:execTransaction
 * 功能说明:基于事务执行SQL语句(SELETE除外)
 * 输入参数:单个SQL语句
 * 输出参数:无
 * 其他说明:无
 */
bool DatabaseCommon::execTransaction(const QString &sqlString)
{
    QMutexLocker locker(&mMutex);
    if(!mDatabase.isOpen())
    {
        qCritical() << "Database is closed.";
        return false;
    }
    if(sqlString.startsWith("SELECT", Qt::CaseInsensitive))
    {
        qCritical() << "Unsupported operation: " << sqlString;
        return false;
    }
    if (!mDatabase.transaction())
    {
        qCritical() << "Failed to begin transaction:" << mDatabase.lastError().text();
        return false;
    }

    QSqlQuery query(mDatabase);

    try
    {
        if (!query.exec(sqlString))
        {
            throw query.lastError();
        }

        // 可选:检查受影响行数
        if (sqlString.trimmed().startsWith("UPDATE", Qt::CaseInsensitive) && query.numRowsAffected() == 0)
        {
            qWarning() << "Warning: No rows affected by:" << sqlString;
        }
        if (!mDatabase.commit())
        {
            throw mDatabase.lastError();
        }

        return true;
    }
    catch (const QSqlError &error)
    {
        if (!mDatabase.rollback())
        {
            qCritical() << "Failed to rollback transaction:" << mDatabase.lastError().text();
        }

        qCritical() << "Transaction failed at command:" << query.lastQuery();
        qCritical() << "Error:" << error.text();
        return false;
    }
}
/*
 * 函数名称:execTransaction
 * 功能说明:基于事务执行SQL语句(SELETE除外)
 * 输入参数:多个SQL语句
 * 输出参数:无
 * 其他说明:无
 */
bool DatabaseCommon::execTransaction(const QStringList &sqlStrings)
{
    QMutexLocker locker(&mMutex);
    if(!mDatabase.isOpen())
    {
        qCritical() << "Database is closed.";
        return false;
    }
    if (!mDatabase.transaction())
    {
        qCritical() << "Failed to begin transaction:" << mDatabase.lastError().text();
        return false;
    }

    QSqlQuery query(mDatabase);

    try
    {
        foreach (const QString &sql, sqlStrings)
        {
            if (!query.exec(sql))
            {
                throw query.lastError();
            }

            // 可选:检查受影响行数
            if (sql.trimmed().startsWith("UPDATE", Qt::CaseInsensitive) && query.numRowsAffected() == 0)
            {
                qWarning() << "Warning: No rows affected by:" << sql;
            }
        }

        if (!mDatabase.commit())
        {
            throw mDatabase.lastError();
        }

        return true;
    }
    catch (const QSqlError &error)
    {
        if (!mDatabase.rollback())
        {
            qCritical() << "Failed to rollback transaction:" << mDatabase.lastError().text();
        }

        qCritical() << "Transaction failed at command:" << query.lastQuery();
        qCritical() << "Error:" << error.text();
        return false;
    }
}

使用示例

QSqlDatabase::addDatabase("QSQLITE", "SysRun");//SysRun是数据库连接名
SysRunDatabase::Instance().setDatabase(QSqlDatabase::database("SysRun", false));
SysRunDatabase::Instance().setDatabaseName("123.db");//123.db是数据库文件名
/*打开数据库连接*/
if(!SysRunDatabase::Instance().openDatabase())
{
	return false;
}
//在此之后就可以增删改查
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐