基于Qt封装数据库基本增删改查操作,支持多线程,并实现SQLite数据库单例访问
·
头文件
#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;
}
//在此之后就可以增删改查
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)