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

基于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;
}
//在此之后就可以增删改查
http://www.lryc.cn/news/2395531.html

相关文章:

  • EC800X QuecDuino开发板介绍
  • ARM P15协处理器指令详解:架构、编程与应用实践
  • PHP轻量级聊天室源码(源码下载)
  • MySQL数据表添加字段(三种方式)
  • leetcode hot100刷题日记——33.二叉树的层序遍历
  • 2、PyTorch基础教程:从张量到神经网络训练
  • 《数据结构初阶》【番外篇:快速排序的前世今生】
  • 【笔记】基于 MSYS2(MINGW64)的 Poetry 虚拟环境创建指南
  • PINNs案例——二维磁场计算
  • Hive SQL 中 BY 系列关键字全解析:从排序、分发到分组的核心用法
  • 数据类型检测有哪些方式?
  • 算法打开13天
  • Freeqwq 世界首个免费无限制 分布式 AI 算力平台 https://qwq.aigpu.cn/
  • 广告拦截器:全方位拦截,畅享无广告体验
  • .net Avalonia应用程序生命周期
  • 主数据编码体系全景解析:从基础到高级的编码策略全指南
  • Selenium操作指南(全)
  • Go语言中的数据类型转换
  • 35、请求处理-【源码分析】-自定义参数绑定原理
  • 智绅科技——科技赋能健康养老,构建智慧晚年新生态
  • STM32通过KEIL pack包轻松移植LVGL,并学会使用GUI guider
  • day43 python Grad-CAM
  • 在 Ubuntu 上挂载其他硬盘的步骤
  • SQL的查询优化
  • MCU如何从向量表到中断服务
  • 物联网基础概念
  • Linux线程同步实战:多线程程序的同步与调度
  • 【MySQL】事务及隔离性
  • Leetcode 3566. Partition Array into Two Equal Product Subsets
  • yolo目标检测助手:具有模型预测、图像标注功能