当前位置: 首页 > news >正文

基于Qt封装数据库基本增删改查操作,支持多线程,并实现SQLite数据库单例访问

抽出来的,直接用就行

  • 头文件
  • CPP文件
  • 使用示例

头文件

#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;
}
//在此之后就可以增删改查

相关文章:

  • 系统架构中的组织驱动:康威定律在系统设计中的应用
  • 【连接器专题】SD卡座规格书审查需要审哪些方面?
  • DeepSeek 赋能文化遗产数字化修复:AI 重构千年文明密码
  • 极简以太彩光网络解决方案4.0正式发布,“彩光”重构园区网络极简之道
  • 中国城市间地理距离矩阵(2024)
  • 显卡3080和4060哪个强 两款游戏性能对比
  • AWS Transit Gateway实战:构建DMZ隔离架构,实现可控的网络互通
  • AWS API Gateway 配置WAF(中国区)
  • 云计算Linux Rocky day02(安装Linux系统、设备表示方式、Linux基本操作)
  • 开源协议:构建全球技术协作的基石
  • 通过回调函数注册定时器触发事件
  • Linux线程池(下)(34)
  • 加强LLM防御以实现企业部署
  • 奇异值分解(SVD):线性代数在AI大模型中的核心工具
  • 计算机一次取数过程分析
  • Error: Flash Download failed - Could not load file “xxx.axf“
  • 【Golang进阶】第七章:错误处理与defer——从优雅回收到异常恢复
  • CQF预备知识:Python相关库 -- NumPy 基础知识 - 结构化数组
  • 编码总结如下
  • ssm 学习笔记 day02
  • 广州十大室内设计公司排名/抖音seo推荐算法
  • 个人网站论文摘要/优化疫情防控措施
  • 做金融资讯网站需要哪些牌照/播放量自助下单平台
  • 惠阳做网站/无屏蔽搜索引擎
  • 网站的配置标题/线上营销怎么做
  • ps 做ui比较好的网站有哪些/产品推广运营方案