Qt封装号的数据库操作类

连接QMYSQL,包含断线重连

头文件(xxx.h)

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QThread.h>
#include <QQueue>
#include <QMutex>
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QSqlError>
#include <QSqlQuery>
#include <QDateTime>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QSqlRecord>
#include <QSettings>
#include <QException>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEtypedef enum DBFlag
{DBALL = 0,DBMYSQL = 1,DBMONGODB = 2,
}EDBFLAG;typedef enum ConnStatus
{INIT = 0,CONNECTED = 1,DISCONNECTED = 2
}EConnStatus;typedef void (*ThreadFunc)(void *);   // 线程回调函数指针定义,threadFunc 类型是 void (*)(void *),表示要static类型函数,而非静态成员函数会隐式地接受一个 this 指针,因此非静态的实际签名是 void (CThread::*)(void *)class  CThread : public QThread
{
public:CThread (QObject *parent = nullptr);~CThread ();bool Start (ThreadFunc pFunc, void *pParam);
protected:virtual void run ();
private:void *m_pThreadParm;ThreadFunc m_pFunc;QMutex m_Mutex;
};class /*XWHCOMMON_EXPORT*/ CReturn
{
public:bool m_bReturn;    // 执行结果返回值,取值范围必须是枚举eCReturnCodeint m_nErrorCode; // 故障代码,取值由函数自定义QString m_sErrMsg = "";            //m_nReturn的异常详细描述CReturn();explicit CReturn(bool bReturn, int nErrorCode = 0, QString sMsg="");~CReturn();CReturn& operator = (const CReturn& ReturnObj){if (this != &ReturnObj)   // longl.jiao 增减是否是自己给自己赋值的判断{m_bReturn = ReturnObj.m_bReturn;m_sErrMsg = ReturnObj.m_sErrMsg;m_nErrorCode = ReturnObj.m_nErrorCode;}else;return *this;}
};
Q_DECLARE_METATYPE(CReturn)//
//定义XwhDbClient 的错误码
//
enum class DBCLIENT_ERROR_CODE : int
{DBCLIENT = 300,OPEN_MYSQL_CLIENT_ERROR, //打开数据库客户端出错SQL_IS_EMPTY,//sql语句为空STRSQL_SIZE_OUTRANGE,//集合strsql的大小越界PARAM_EMPTY,
};#define DB_OBJ CDbClient::GetInstance()
class /*CDbClient_EXPORT*/ CDbClient : public QThread
{Q_OBJECTpublic://// 功能: 单实例通过此接口,获取数据交交互对象// 返回: 返回引用,避免用指针// 调用方法:// 主要思路://static CDbClient& GetInstance();//// 功能: 一键导出数据库中表的数据(csv格式)// 返回:// 调用方法:// 主要思路://bool saveToCsv(const QString& sSql, QList<QMap<QString, QVariant>>& result);//// 功能: 调用其他函数前,先调用此函数,它将连接数据库,准备好交互线程// 返回:// 调用方法:// 主要思路:CReturn Init();//// 功能: 停止数据库线程,并释放数据库连接对象,对应Init函数// 返回:// 调用方法:// 主要思路:CReturn UnInit();//// 功能: (同步接口)对MySql执行Select语句// 参数: sSql一次只能执行一条查询语句;result为List,一个元素为关系表的一行记录,//        一行记录又以Map的形式存储,Key为关系表的列名,Value为对应的值// 调用方法:// 主要思路:CReturn QueryMySql(const QString sSql, QList< QMap<QString, QVariant> >& result);//// 功能: (同步接口)对MySql执行增、删、改语句,此数据比较危险,请慎用// 参数:// 调用方法:// 主要思路:CReturn ExecMySql(const QString sSql);//// 功能: (同步接口)批量对MySql执行增、删、改语句// 参数:// 调用方法:lStrSql size必须小于等于100,否则会报错.// 主要思路:批量插入sqlCReturn ExecMySql(const QList<QString>& lStrSql);//// 功能: (同步接口)批量对MySql执行增、删、改语句// 参数:// 调用方法:// 主要思路:批量插入sqlCReturn ExecMySql(const QString sSql, const QMap<QString, QVariant>& mParam);//// 功能: 先执行增删除,再查询// 参数:// 调用方法:// 主要思路:CReturn ExecAndQueryMySql(const QString sExeSql, const QString sQuerySql, QList< QMap<QString, QVariant> >& result);//// 功能: mysql连接状态// 参数:// 调用方法:// 主要思路:EConnStatus GetMysqlConnStatus();//// 功能: 获取数据库所有表名称// 参数:// 调用方法:// 主要思路:CReturn GetAllTableName(QVector<QString>& vec_TableName);//// 功能: 开始事务操作// 参数:// 调用方法:// 主要思路:CReturn BeganTransaction();//// 功能: 提交// 参数:// 调用方法:// 主要思路:CReturn CommitTransaction();//// 功能: 回滚// 参数:// 调用方法:// 主要思路:CReturn RollbackTransaction();CReturn NoTransactionExec(const QString& sSql);CReturn NoTransactionExecSql(const QString& strSql, bool& execOk);//// 功能: 保存线程// 参数:// 调用方法:// 主要思路:///static void ThreadFunc_SaveFunction(void* pParam);CReturn UpdateAttribute(QString, QString);CReturn _InitValue();CReturn GetIntValue(const QString& sCategory, const QString& sKey, int& nValue);private:CDbClient(QObject* parent = nullptr);~CDbClient();//// 功能: 初始化mysql// 参数:// 返回:// 调用方法:// 主要思路:建立mysql连接CReturn InitMysql(bool breconnect = false);//// 功能: 初始化mysql// 参数:// 返回:// 调用方法:// 主要思路:建立MongoDB连接//CReturn InitMongoDB(bool breconnect = false);//// 功能: 停止mysql连接// 参数:// 返回:// 调用方法:// 主要思路:停止mysql连接void UnInitMysql();//// 功能: 停止MongoDB连接// 参数:// 返回:// 调用方法:// 主要思路:停止MongoDB连接//void UnInitMongoDB();//// 功能: MySql交互线程实体函数,从队列中提取、并执行任务(对数据库进行增、删、改查工作)// 参数:// 返回:// 调用方法:// 主要思路:里面死循环,调用ReleaseRes退出void MysqlRun();//断线重连//// 功能: MongoDb交互线程实体函数,从队列中提取、并执行任务(对数据库进行增、删、改查工作)// 参数:// 返回:// 调用方法:// 主要思路:里面死循环,调用ReleaseRes退出//void MongoDBRun();//// 功能: mysql心跳// 参数:// 返回:// 调用方法:// 主要思路:发送查询CReturn MysqlHeatBeat();//// 功能: MongoDB 心跳// 参数:// 返回:// 调用方法:// 主要思路:发送命令//CReturn MongoDBHeatBeat();//// 功能: 当alams_process表数据达到10万条时,以csv方式保存并清空表// 参数:// 返回:// 调用方法:// 主要思路:void exportToCsv(const QString& tableName, const QString& outputCsv);//// 功能: (同步接口)对MySql执行Select语句// 参数: sSql一次只能执行一条查询语句;result为List,一个元素为关系表的一行记录,//        一行记录又以Map的形式存储,Key为关系表的列名,Value为对应的值// 调用方法:// 主要思路:bool QueryMySqlIn(const QString& sSql, QList< QMap<QString, QVariant> >& result, QString& sNativeErrCode, QString& sErrMsg);//// 功能: (同步接口)对MySql执行增、删、改语句,此数据比较危险,请慎用// 参数:// 调用方法:// 主要思路:bool ExecMySqlIn(const QString& sSql, QString& sNativeErrCode, QString& sErrMsg);//// 功能: (同步接口)批量对MySql执行增、删、改语句// 参数:// 调用方法:lStrSql size必须小于等于100,否则会报错.// 主要思路:批量插入sqlbool ExecMySqlIn(const QList<QString>& lStrSql, QString& sNativeErrCode, QString& sErrMsg);///// 功能: 将对位前后相机的参数保存到数据库// 参数:// 调用方法:// 主要思路:l//void saveResultToDB(AlgMS_param param1, AlgMS_result result1);//// 功能: (同步接口)批量对MySql执行增、删、改语句// 参数:// 调用方法:// 主要思路:批量插入sqlbool ExecMySqlIn(const QString& sSql, const QMap<QString, QVariant>& mParam, QString& sNativeErrCode, QString& sErrMsg);//// 功能: 先执行增删除,再查询// 参数:// 调用方法:// 主要思路:bool ExecAndQueryMySqlIn(const QString& sExeSql, const QString& sQuerySql, QList< QMap<QString, QVariant> >& result, QString& sNativeErrCode, QString& sErrMsg);//************************************************************************// 功能描述:  创建MYSQL表// 参    数: 表名// 返 回 值:  true:成功  false: 失败// 主要思路:// 调用方法:// 作者时间://************************************************************************bool CreateTable(const std::wstring strTableName);//************************************************************************// 功能描述:  执行MYSQL语句// 参    数: MYSQL语句// 返 回 值:  true:成功  false: 失败// 主要思路:// 调用方法:// 作者时间://************************************************************************bool ExecSql(const QString& strSql);//************************************************************************// 功能描述:  创建MYSQL产能表// 参    数:// 返 回 值:  true:成功  false: 失败// 主要思路:// 调用方法:// 作者时间://************************************************************************bool CreateCapacityTable();//************************************************************************// 功能描述:  获取数据库中所有表名// 参    数: 表名// 返 回 值:  true:成功  false: 失败// 主要思路:// 调用方法:// 作者时间://************************************************************************bool QueryAllTableFromSQlite(std::vector<std::wstring>& vcTableName);//************************************************************************// 功能描述:  执行MYSQL语句,并返回需要的值// 参    数: MYSQL语句// 返 回 值:  QSqlQuery// 主要思路:// 调用方法:// 作者时间://************************************************************************QSqlQuery Query(const QString& strSql);public:static void ThreadFunc_MySql(void* pParam);//static void ThreadFunc_MongoDb(void* pParam);private://QQueue< XwhDbTaskParam > m_QueueMysqlTask;    //任务队列//QMutex m_QueueMysqlMutex;                    //任务队列的互斥量,保护queueTask队列QSqlDatabase m_MysqlClient;                    //数据库连接对象QMutex m_MysqlMutex;                           //m_DB互斥量,保护m_DB访问权限CThread m_MysqlThread;                          //mysql线程断线连接线程对象bool m_bMysqlRunning;                          //标志断线重连线程运行状态,true为运行中,false为未运行,第一次初始化连接后就需设置true,在不用连接数据库后设置为falseQMutex m_InitAndUnInitMutex;                   //初始化和反初始化锁,保证初始化操作和反初始化操作只能存在一次线程在执行EConnStatus m_nMysqlConnStatus;                //mysql连接状态QMap<QString, QString>                  m_mapConfig;				//  配置信息int                                     m_nDataStatu;               //  标志从数据库、配置文件加载数据的状态,0:初始状态,1:正在下载数据, 2:完成下载, 3:下载错误};class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

源文件(xxx.cpp)

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);CReturn res = DB_OBJ.Init();res = DB_OBJ._InitValue();
}MainWindow::~MainWindow()
{delete ui;
}CDbClient &CDbClient::GetInstance()
{static CDbClient s_Instance;return s_Instance;
}bool CDbClient::saveToCsv(const QString &sSql, QList<QMap<QString, QVariant> > &result)
{QDateTime startPrintTime = QDateTime::currentDateTime();// 获取当前时间QString timeStr = startPrintTime.toString("yyyyMMdd_HHmmss"); // 转换为字符串格式QFile file("D:/" + timeStr + ".csv");// 创建以时间命名的csv文件if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){return false;}QString sNativeErrCode, sErrMsg;bool bIsOk = QueryMySqlIn(sSql, result, sNativeErrCode, sErrMsg);if (bIsOk){QTextStream out(&file);out << "id,category,primarykey,value,optional,min,max,defaultval,datatype,status,comments" << endl;for (const QMap<QString, QVariant>& itemMap : result){//写入csv文件的内容QString id = itemMap["id"].toString();QString category = itemMap["category"].toString();QString primarykey = itemMap["primarykey"].toString();QString value = itemMap["value"].toString();QString optional = itemMap["optional"].toString();QString min = itemMap["min"].toString();QString max = itemMap["max"].toString();QString defaultval = itemMap["defaultval"].toString();QString datatype = itemMap["datatype"].toString();QString status = itemMap["status"].toString();QString comments = itemMap["comments"].toString();out << id << "," << category << "," << primarykey << "," << value << "," << optional << "," << min << "," << max << "," << defaultval << "," << datatype << "," << status << "," << comments << endl;}file.close();}else{qDebug() << "查询数据失败,错误代码:" << sNativeErrCode << ",错误信息:" << sErrMsg;}return true;
}CReturn CDbClient::Init()
{CReturn ret;ret = InitMysql();if (true != ret.m_bReturn){return ret;}else;//ret = InitMongoDB();//if (true != ret.m_bReturn)//{//	return ret;//}//else;return ret;
}CReturn CDbClient::UnInit()
{CReturn ret;UnInitMysql();//UnInitMongoDB();return ret;
}CReturn CDbClient::QueryMySql(const QString sSql, QList<QMap<QString, QVariant> > &result)
{if (sSql.isEmpty()){return CReturn(false, (int)DBCLIENT_ERROR_CODE::SQL_IS_EMPTY, tr("Sql is empty, please check the code"));}else;QString sNatvieCode = "";QString sErrMsg = "";bool bIsOk = QueryMySqlIn(sSql, result, sNatvieCode, sErrMsg);//重连CReturn ret;if (false == bIsOk && ("2003" == sNatvieCode || "2013" == sNatvieCode))//2003 无法连接到指定的MySQL服务器 2013在查询过程中失去了与MySQL服务器的连接{ret = InitMysql(true);}else;if (true == ret.m_bReturn){bIsOk = QueryMySqlIn(sSql, result, sNatvieCode, sErrMsg);}else;return CReturn(bIsOk, 0, sErrMsg);
}CReturn CDbClient::ExecMySql(const QString sSql)
{if (sSql.isEmpty()){return CReturn(false, (int)DBCLIENT_ERROR_CODE::SQL_IS_EMPTY, tr("sql is empty."));}else;QString sNatvieCode = "";QString sErrMsg = "";bool bIsOk =  ExecMySqlIn(sSql, sNatvieCode, sErrMsg);CReturn ret;if (false == bIsOk && ("2003" == sNatvieCode || "2013" == sNatvieCode)){ret = InitMysql(true);}else;if (true == ret.m_bReturn){bIsOk = ExecMySqlIn(sSql, sNatvieCode, sErrMsg);}else;return CReturn(bIsOk, 0, sErrMsg);
}CReturn CDbClient::ExecMySql(const QList<QString> &lStrSql)
{if (lStrSql.size() > 200){return CReturn(false, (int)DBCLIENT_ERROR_CODE::STRSQL_SIZE_OUTRANGE, tr("lStrSql size greater than 200, please check."));}else;QString sNatvieCode = "";QString sErrMsg = "";bool bIsOk = ExecMySqlIn(lStrSql, sNatvieCode, sErrMsg);CReturn ret;if (false == bIsOk && ("2003" == sNatvieCode || "2013" == sNatvieCode)){ret = InitMysql(true);}else;if (true == ret.m_bReturn){bIsOk = ExecMySqlIn(lStrSql, sNatvieCode, sErrMsg);}else;return CReturn(bIsOk, 0, sErrMsg);
}CReturn CDbClient::ExecMySql(const QString sSql, const QMap<QString, QVariant> &mParam)
{if (sSql.isEmpty()){return CReturn(false, (int)DBCLIENT_ERROR_CODE::SQL_IS_EMPTY, tr("sql is empty."));}else;if (mParam.isEmpty()){return CReturn(false, (int)DBCLIENT_ERROR_CODE::PARAM_EMPTY, tr("mParam size is zero."));}else;QString sNatvieCode = "";QString sErrMsg = "";bool bIsOk = ExecMySqlIn(sSql, mParam, sNatvieCode, sErrMsg);CReturn ret;if (false == bIsOk && ("2003" == sNatvieCode || "2013" == sNatvieCode)){ret = InitMysql(true);}else;if (true == ret.m_bReturn){bIsOk = ExecMySqlIn(sSql, mParam, sNatvieCode, sErrMsg);}else;return CReturn(bIsOk, 0, sErrMsg);
}CReturn CDbClient::ExecAndQueryMySql(const QString sExeSql, const QString sQuerySql, QList<QMap<QString, QVariant> > &result)
{QString sNatvieCode = "";QString sErrMsg = "";bool bIsOk = ExecAndQueryMySqlIn(sExeSql, sQuerySql, result, sNatvieCode, sErrMsg);CReturn ret;if (false == bIsOk && ("2003" == sNatvieCode || "2013" == sNatvieCode)){ret = InitMysql(true);}else;if (true == ret.m_bReturn){bIsOk = ExecAndQueryMySqlIn(sExeSql, sQuerySql, result, sNatvieCode, sErrMsg);}else;return CReturn(bIsOk, 0, sErrMsg);
}EConnStatus CDbClient::GetMysqlConnStatus()
{return m_nMysqlConnStatus;
}CReturn CDbClient::GetAllTableName(QVector<QString> &sVecTableName)
{QMutexLocker locker(&m_MysqlMutex);QSqlQuery query(m_MysqlClient);QString sExecSql = QString("select table_name from information_schema.tables where table_schema = 'xwh_newdb' AND table_type = 'BASE TABLE';");query.exec(sExecSql);while (query.next()){sVecTableName.push_back(query.value(0).toString());}QString sErrMsg = query.lastError().text();return CReturn(true, 0, sErrMsg);
}CReturn CDbClient::BeganTransaction()
{QMutexLocker locker(&m_MysqlMutex);if (m_MysqlClient.transaction()){return CReturn(true);}else;return CReturn(false);
}CReturn CDbClient::CommitTransaction()
{QMutexLocker locker(&m_MysqlMutex);if (m_MysqlClient.commit()){return CReturn(true);}else;return CReturn(false);
}CReturn CDbClient::RollbackTransaction()
{QMutexLocker locker(&m_MysqlMutex);if (m_MysqlClient.rollback()){return CReturn(true);}else;return CReturn(false);
}CReturn CDbClient::NoTransactionExec(const QString &sSql)
{QMutexLocker locker(&m_MysqlMutex);bool result = false;NoTransactionExecSql(sSql, result);if (!result){RollbackTransaction();return CReturn(false);}else;return CReturn(true);
}CReturn CDbClient::NoTransactionExecSql(const QString &sSql, bool &bExecOk)
{QMutexLocker locker(&m_MysqlMutex);CReturn retValue = ExecMySql(sSql);if (retValue.m_bReturn){bExecOk = true;}else{bExecOk = false;}return retValue;
}void CDbClient::ThreadFunc_SaveFunction(void *pParam)
{//无
}CReturn CDbClient::UpdateAttribute(QString UvAttribute, QString key)
{CReturn ReturnValue(true);do{QMutexLocker locker(&m_MysqlMutex);QSqlQuery query(m_MysqlClient);QString sql = QString("UPDATE datacachecenter SET value = :value where primarykey = :key");if (query.prepare(sql)){query.bindValue(":value", UvAttribute);query.bindValue(":key",key);if (!query.exec()){ReturnValue.m_sErrMsg = query.lastError().text();ReturnValue.m_bReturn = false;break;}else;}else{ReturnValue.m_sErrMsg = QString("Fail to sql Prepare");ReturnValue.m_bReturn = false;}} while (0);return ReturnValue;
}CDbClient::CDbClient(QObject *parent):QThread(parent), m_bMysqlRunning(false)
{qRegisterMetaType< QList< QMap<QString, QVariant> > >("QList< QMap<QString, QVariant> >");qRegisterMetaType< CReturn  >("CReturn ");//m_MongoDBClient = NULL;                      //MongoDB数据库连接对象m_nMysqlConnStatus = EConnStatus::INIT;
}CDbClient::~CDbClient()
{UnInit();
}bool FileIsExist(const QString& sFile)
{QFile tempFile(sFile);return tempFile.exists();
}CReturn GetIniFileValue(const QString& sPath, const QString& sKey, const QVariant& defaultValue, QVariant& GetValue)
{CReturn xwhReturn(true);do{if (!FileIsExist(sPath)){xwhReturn = CReturn(false, 0, QString(QObject::tr("Failed to get Ini file[%1] key[%2], Error:File not exist")).arg(sPath).arg(sKey));break;}else;try{QSettings IniObj(sPath, QSettings::Format::IniFormat);GetValue = IniObj.value(sKey, defaultValue);}catch (QException e){xwhReturn = CReturn(false, 0, QString(QObject::tr("Failed to get Ini file[%1] key[%2], Error:[%3]")).arg(sPath).arg(sKey).arg(e.what()));}} while (0);return xwhReturn;
}QString GetXOREncryptUncrypt(QString sStr)
{QByteArray text = sStr.toLocal8Bit();QByteArray by = text.fromBase64(text);QString sRe = QString::fromLocal8Bit(by); // 注意:这里是处理中文用的return sRe;
}CReturn CDbClient::InitMysql(bool breconnect)
{CReturn Return;QMutexLocker locker(&m_MysqlMutex);do{if (true == m_bMysqlRunning && false == breconnect){Return = CReturn(false, -1, tr("Mysql have be Inited , before do this, you must call the UnInit first"));break;}else;//从配置文件获取数据库登录信息QVariant GetValue;QString sIP, sUser, sPW, sDB;int nPort = 0;
# if 0Return = GetIniFileValue("../config.ini", "MySqlDB", "", GetValue);if (Return.m_bReturn != true){break;}else;sDB = GetValue.toString();Return = GetIniFileValue("../config.ini", "MySqlIP", "", GetValue);if (Return.m_bReturn != true){break;}else;sIP = GetValue.toString();Return = GetIniFileValue("../config.ini", "MySqlPORT", "", GetValue);if (Return.m_bReturn != true){break;}else;nPort = GetValue.toInt();Return = GetIniFileValue("../config.ini", "MySqlUserName", "", GetValue);if (Return.m_bReturn != true){break;}else;sUser = GetValue.toString();Return = GetIniFileValue("../config.ini", "MySqlPW", "", GetValue);if (Return.m_bReturn != true){break;}else;sPW = GetValue.toString();//sPW = GetXOREncryptUncrypt(sPW);  //调试暂时屏蔽密码加密//重连关闭if (true == breconnect){m_MysqlClient.close();}else;
#endifm_MysqlClient = QSqlDatabase::addDatabase("QMYSQL");m_MysqlClient.setDatabaseName(/*sDB*/"dier_newdata");m_MysqlClient.setHostName(/*sIP*/"127.0.0.1");m_MysqlClient.setPort(/*nPort*/3306);m_MysqlClient.setUserName(/*sUser*/"root");m_MysqlClient.setPassword(/*sPW*/"");if (!m_MysqlClient.open()){//M 写日志 qDebug() << "sqlError" << m_MysqlClient.lastError();Return.m_bReturn = false;Return.m_nErrorCode = 0;Return.m_sErrMsg = m_MysqlClient.lastError().text();m_nMysqlConnStatus = EConnStatus::DISCONNECTED;break;}else{Return.m_bReturn = true;Return.m_sErrMsg = "";Return.m_nErrorCode = -4; //??m_nMysqlConnStatus = EConnStatus::CONNECTED;}//重连时不重复开启线程,第一次初始化连接数据库的时候执行设置false,然后不用连接数据库时也应设falseif (false == breconnect){m_bMysqlRunning = true;m_MysqlThread.Start(ThreadFunc_MySql, this);}else;} while (0);return Return;
}void CDbClient::UnInitMysql()
{m_bMysqlRunning = false;if (m_MysqlThread.isRunning()){//QThread::msleep(10);m_MysqlThread.quit();m_MysqlThread.wait();}else;m_MysqlClient.close();
}void CDbClient::MysqlRun()
{CReturn ret;int nHBTime = 30;int nCnt = 30;while (m_bMysqlRunning)//{if (nCnt++ < 30){QThread::sleep(1);//休眠1秒,确保能够及时退出线程continue;}else;//每个30秒发送一个心跳,保证连接不会超时nCnt = 0;ret = MysqlHeatBeat();if (true != ret.m_bReturn){ret = InitMysql(true);if (true != ret.m_bReturn){m_nMysqlConnStatus = EConnStatus::DISCONNECTED;//qDebug() << "mysql disconnet,err_msg:" << ret.m_sErrMsg;if (300 < nHBTime) {nHBTime *= 2;}else;}else;}else{m_nMysqlConnStatus = EConnStatus::CONNECTED;//qDebug() << "mysql reconnet succ.";nHBTime = 30;}}
}CReturn CDbClient::MysqlHeatBeat()
{QString sSql = "SELECT VERSION();";QList< QMap<QString, QVariant> > lResult;QMutexLocker locker(&m_MysqlMutex);QSqlQuery query(m_MysqlClient);bool bIsOk = false;try{bIsOk = query.exec(sSql);while (query.next()){QMap<QString, QVariant> itemMap;QSqlRecord record = query.record();for (int index = 0; index < record.count(); index++){itemMap[record.fieldName(index)] = record.value(index);}lResult.push_back(itemMap);}//        while (query.next())//        {//            int id = query.value(0).toInt();//            QString username = query.value(1).toString();//            QString password = query.value(2).toString();//            qDebug() << "ID:" << id << "Username:" << username << "Password:" << password;//        }}catch (...){bIsOk = false;}return CReturn(bIsOk, 0, query.lastError().text());
}void CDbClient::exportToCsv(const QString &tableName, const QString &outputCsv)
{}bool CDbClient::QueryMySqlIn(const QString &sSql, QList<QMap<QString, QVariant> > &result, QString &sNativeErrCode, QString &sErrMsg)
{bool bIsOk = false;QMutexLocker locker(&m_MysqlMutex);QSqlQuery query(m_MysqlClient);try{bIsOk = query.exec(sSql);while (query.next()){QMap<QString, QVariant> itemMap;QSqlRecord record = query.record();for (int index = 0; index < record.count(); index++){itemMap[record.fieldName(index)] = record.value(index);}result.push_back(itemMap);}}catch (...){bIsOk = false;}sNativeErrCode = query.lastError().nativeErrorCode();sErrMsg = query.lastError().text();return bIsOk;
}bool CDbClient::ExecMySqlIn(const QString &sSql, QString &sNativeErrCode, QString &sErrMsg)
{QMutexLocker locker(&m_MysqlMutex);QSqlQuery query(m_MysqlClient);bool bIsOk = false;try{bIsOk = query.exec(sSql);}catch (...){bIsOk = false;}sNativeErrCode = query.lastError().nativeErrorCode();sErrMsg = query.lastError().text();return bIsOk;
}bool CDbClient::ExecMySqlIn(const QList<QString> &lStrSql, QString &sNativeErrCode, QString &sErrMsg)
{QMutexLocker locker(&m_MysqlMutex);QSqlQuery query(m_MysqlClient);bool bIsOk = m_MysqlClient.transaction();if (!bIsOk){sNativeErrCode = m_MysqlClient.lastError().nativeErrorCode();sErrMsg = m_MysqlClient.lastError().text();return bIsOk;}else;try{for (int i = 0; i < lStrSql.size(); ++i){QString sSql = lStrSql.at(i);bIsOk = query.exec(sSql);if (false == bIsOk){break;}else;}}catch (...){bIsOk = false;}if (bIsOk){m_MysqlClient.commit();}else{m_MysqlClient.rollback();sNativeErrCode = m_MysqlClient.lastError().nativeErrorCode();sErrMsg = m_MysqlClient.lastError().text();}return bIsOk;
}bool CDbClient::ExecMySqlIn(const QString &sSql, const QMap<QString, QVariant> &mParam, QString &sNativeErrCode, QString &sErrMsg)
{QMutexLocker locker(&m_MysqlMutex);QSqlQuery query(m_MysqlClient);bool bIsOk = false;do {try{bIsOk = query.prepare(sSql);if (false == bIsOk){break;}else;//参数绑定for (QMap<QString, QVariant>::const_iterator it = mParam.begin(); it != mParam.end(); it++){query.bindValue(it.key(), it.value());    //QDX 转换被作为参数的换位value;}bIsOk = query.exec();}catch (...){bIsOk = false;}} while (0);sNativeErrCode = query.lastError().nativeErrorCode();sErrMsg = query.lastError().text();return bIsOk;
}bool CDbClient::ExecAndQueryMySqlIn(const QString &sExeSql, const QString &sQuerySql, QList<QMap<QString, QVariant> > &result, QString &sNativeErrCode, QString &sErrMsg)
{QMutexLocker locker(&m_MysqlMutex);QSqlQuery query(m_MysqlClient);bool bIsOk = false;do {bIsOk = m_MysqlClient.transaction();if (false == bIsOk){break;}else;bIsOk = query.exec(sExeSql);if (false == bIsOk){m_MysqlClient.rollback();break;}else;bIsOk = query.exec(sQuerySql);if (false == bIsOk){m_MysqlClient.rollback();break;}else;while (query.next()){QMap<QString, QVariant> itemMap;QSqlRecord record = query.record();for (int index = 0; index < record.count(); index++){itemMap[record.fieldName(index)] = record.value(index);}result.push_back(itemMap);}m_MysqlClient.commit();} while (0);sNativeErrCode = query.lastError().nativeErrorCode();sErrMsg = query.lastError().text();return bIsOk;
}#define CAPACITYTABLE L"capacitytable"
bool CDbClient::CreateTable(const std::wstring strTableName)
{bool bRet = true;QString strExecSql = "";if (strTableName.compare(CAPACITYTABLE) == 0){strExecSql = QString("CREATE TABLE %1(Id INT AUTO_INCREMENT PRIMARY KEY,\Date DATE,\Entry_plate_time TIME,\Out_plate_time TIME,\Board_in_to_board_out_time DOUBLE,\Counterpoint_time DOUBLE,\Printing_time DOUBLE,\Platform_number TEXT,\Work_order_ID DOUBLE,\Employee_ID	DOUBLE,\Production_part_number TEXT,\Plate_thickness DOUBLE,\WorkPlatformA_or_WorkPlatformB TEXT,\UV1_pass1 DOUBLE,\UV1_pass2 DOUBLE,\UV1_pass3 DOUBLE,\UV1_pass4 DOUBLE,\UV2_pass1 DOUBLE,\UV2_pass2 DOUBLE,\UV2_pass3 DOUBLE,\UV2_pass4 DOUBLE,\UV3_pass1 DOUBLE,\UV3_pass2 DOUBLE,\UV3_pass3 DOUBLE,\UV3_pass4 DOUBLE,\UV4_pass1 DOUBLE,\UV4_pass2 DOUBLE,\UV4_pass3 DOUBLE,\UV4_pass4 DOUBLE,\UV5_pass1 DOUBLE,\UV5_pass2 DOUBLE,\UV5_pass3 DOUBLE,\UV5_pass4 DOUBLE,\Print_resolution DOUBLE,\PlatformA_Print_origin TEXT,\PlatformB_Print_origin TEXT,\Head1_temperature DOUBLE,\Head2_temperature DOUBLE,\Head3_temperature DOUBLE,\Head4_temperature DOUBLE,\Head5_temperature DOUBLE,\Head6_temperature DOUBLE,\Head7_temperature DOUBLE,\Head8_temperature DOUBLE,\Head9_temperature DOUBLE,\Head10_temperature DOUBLE,\Head11_temperature DOUBLE,\Head12_temperature DOUBLE,\Head13_temperature DOUBLE,\Head14_temperature DOUBLE,\Head15_temperature DOUBLE,\Head16_temperature DOUBLE,\Head17_temperature DOUBLE,\Head18_temperature DOUBLE,\Production_plate_size DOUBLE,\Gross_area DOUBLE,\Production_quantity DOUBLE,\Total_capacity DOUBLE,\Total_production_time DOUBLE);").arg(QString::fromUtf16((const ushort*)strTableName.c_str()));}else;bRet = ExecSql(strExecSql);return bRet;
}bool CDbClient::ExecSql(const QString &strSql)
{QMutexLocker locker(&m_MysqlMutex);bool bACID = m_MysqlClient.transaction();QSqlQuery query(m_MysqlClient);if (bACID){if (query.exec(strSql)){return m_MysqlClient.commit();}else{//LOGWARNNINGCOM(L"ExecSql failed, sql: %s, error: %s.", (const wchar_t*)(strSql.utf16()), (const wchar_t*)(m_MysqlClient.lastError().databaseText().utf16()));//LOGWARNNINGCOM(L"ExecSql failed, sql: %s, error: %s.", (const wchar_t*)(strSql.utf16()), (const wchar_t*)(query.lastError().text().utf16()));return m_MysqlClient.rollback();}}return query.exec(strSql);
}void CDbClient::ThreadFunc_MySql(void *pParam)
{if (NULL == pParam)return;else;CDbClient* pThis = (CDbClient*)pParam;pThis->MysqlRun();
}CReturn::CReturn()
{m_bReturn    = false;   // 默认是异常,正常情况必须自行赋值m_sErrMsg    = "";m_nErrorCode = 0;
}CReturn::CReturn(bool bReturn, int nErrorCode, QString sMsg)
{m_bReturn    = bReturn;m_nErrorCode = nErrorCode;m_sErrMsg    = sMsg;
}CReturn::~CReturn()
{}CThread::CThread(QObject *parent): QThread (parent)
{m_pFunc = nullptr;m_pThreadParm = nullptr;
}CThread::~CThread ()
{this->deleteLater();this->wait();
}void CThread::run ()
{if (nullptr != m_pFunc){m_pFunc (m_pThreadParm);}
}bool CThread::Start (ThreadFunc pFunc, void *pParam)
{QMutexLocker lock(&m_Mutex);bool bRet = false;if (!this->isRunning () && NULL != pFunc){m_pFunc = pFunc;m_pThreadParm = pParam;this->start();bRet = true;}else{// 这个线程还没有结束,不能重新启动bRet = false;}return bRet;
}//	初始化数据中心参数值
CReturn CDbClient::_InitValue()
{CReturn retValue(true);do{QString sSql = "select category,primarykey,value from datacachecenter";QList< QMap<QString, QVariant> > lstResult;retValue = DB_OBJ.QueryMySql(sSql, lstResult);if (true == retValue.m_bReturn){//获取数据库成功for (int i = 0; i < lstResult.size(); i++){const QMap<QString, QVariant>& mapOneData = lstResult.at(i);if (mapOneData["category"].toString().isEmpty() || mapOneData["primarykey"].toString().isEmpty()){//如果类别或者键值为空,则跳过continue;}else;m_mapConfig[mapOneData["category"].toString() + "." + mapOneData["primarykey"].toString()] = mapOneData["value"].toString();}}else{//获取数据库失败retValue.m_bReturn = false;retValue.m_sErrMsg = QObject::tr("Init DbClient  datacachecenter value error:") + retValue.m_sErrMsg;break;}} while (0);return retValue;
}CReturn CDbClient::GetIntValue(const QString& sCategory, const QString& sKey, int& nValue)
{CReturn retValue(true);if (sCategory.trimmed().isEmpty() || sKey.trimmed().isEmpty()){//若输入的类别和键为空,直接返回retValue.m_bReturn = false;retValue.m_sErrMsg = QObject::tr("The category or key is empty.,please packaged logs and send developer.");//LOGERROR(retValue.m_sErrMsg);return retValue;}else;int nTimes = 0;do{while (m_nDataStatu != 2 && nTimes < 5000){nTimes += 500;QThread::msleep(500);}if (nTimes >= 5000){retValue.m_bReturn = false;retValue.m_sErrMsg = QObject::tr("GetValue about sKey(%1) timeout,please packaged logs and send developer.").arg(sKey);//LOGERROR(retValue.m_sErrMsg);break;}else;QString strValue = m_mapConfig[sCategory + "." + sKey];nValue = strValue.toInt();} while (0);return retValue;
}


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/34134.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用一个实例看如何分享大量照片 续篇一

继续上篇的实例分享&#xff0c;在此罗列一些应该注意的细节&#xff0c;以便在下次可以更加省时省力。 最重要的是呈现构想&#xff0c;如按活动/主题、班级/板块、地区/国家等等&#xff0c;这些都应该事先计划好&#xff0c;事后改动工作量巨大&#xff0c;因为太容易出错&a…

中东文明史

转自&#xff1a;想要了解完整的中东文明史&#xff1f;这篇文章成全你 - 知乎 (zhihu.com) 写在前面 中东文明是人类历史上最古老的文明。人类祖先从东非大裂谷走出之后&#xff0c;首先选择定居在中东地区的新月沃土上&#xff0c;并建立了人类历史上有文字记载的第一个文明…

java课程设计GUI学生信息管理系统

目录 系统内容.. 3 用户界面模块... 4 数据存储模块... 4 信息管理模块... 4 管理模块.. 4 主要模块的算法描述... 4 –简要的语言描述... 4 运行及调试分析&#xff08;测试数据及测试结果&#xff09;.. 5 课程设计总结... 7 参考文献&#xff08;至少三个&#xf…

大林 PID 算法

Dahlin PID算法是一种用于控制和调节系统的比例积分延迟算法。以下是一个简单的C语言实现示例&#xff1a; #include <stdio.h>// DALIN PID 结构体定义 typedef struct {float SetPoint; // 设定点float Proportion; // 比例float Integral; // 积分float Derivativ…

vite:配置打包后js的文件名,解决更新后浏览器缓存问题(了解浏览器的强缓存与协商缓存)

目录 第一章 简单理解浏览器的缓存机制 1.1 什么是缓存 1.2 强缓存 1.3 协商缓存 第二章 配置输出js文件名 2.1 原因 2.2 配置代码 第一章 简单理解浏览器的缓存机制 1.1 什么是缓存 当我们第一次访问网站的时候&#xff0c;我们的电脑会把网站上的图片和数据下载到电…

如何优雅地使用 console.log 打印数组或对象

一、背景 使用 console.log 在控制台中打印数组或者对象时&#xff0c;很多时候它们的字段都是默认关闭的&#xff0c;需要手动一个个的点开&#xff0c;非常不直观且麻烦。 二、解决方案 使用 JSON.stringify() 的第三个参数 我们来看一下官方对于 JSON.stringify 的介绍 三、…

Gitee 的公钥删不掉

公钥管理里已经没有公钥了&#xff0c; 仓库里还有&#xff0c;这是怎么回事&#xff1f; 这两个好像又没什么关系。 那为啥要搞两处呢&#xff1f; 个人信息里的公钥一直就没有仓库里使用的公钥&#xff0c; 删掉个人信息里的也没什么影响。 在仓库管理页面导入新公钥提示已…

AI 大模型企业应用实战(06)-初识LangChain

LLM大模型与AI应用的粘合剂。 1 langchain是什么以及发展过程 LangChain是一个开源框架&#xff0c;旨在简化使用大型语言模型构建端到端应用程序的过程&#xff0c;也是ReAct(reasonact)论文的落地实现。 2022年10月25日开源 54K star 种子轮一周1000万美金&#xff0c;A轮2…

解决vscode运行js时突然报错

1. 问题背景 创建JavaScript文件运行&#xff0c;弹出错误&#xff1a;Can’t find Node.js binary “node”: path does not exist. Make sure Node.js is installed and in your PATH, or set the “runtimeExecutable” in your launch.json 这是由于没有配置好setting.js…

C语言入门系列:从内存原理看函数的值传递和引用传递

文章目录 一&#xff0c;值传递二&#xff0c;引用传递三&#xff0c;从内存原理看值传递和引用传递的区别1 值传递内存示意图2 引用传递内存示意图 参考文献 函数参数用于向函数传递数据&#xff0c;C语言支持两种传递方式&#xff1a;值传递和引用传递。 一&#xff0c;值传递…

工程文档CAD转换必备!在 Java 中将 DWG 转换为 JPG

Aspose.CAD 是一个独立的类库&#xff0c;以加强Java应用程序处理和渲染CAD图纸&#xff0c;而不需要AutoCAD或任何其他渲染工作流程。该CAD类库允许将DWG, DWT, DWF, DWFX, IFC, PLT, DGN, OBJ, STL, IGES, CFF2文件、布局和图层高质量地转换为PDF和光栅图像格式。 Aspose AP…

Synchronized、volatile与ReentrantLock:比较这些同步机制在Java并发编程中的应用和区别

在Java并发编程中&#xff0c;确保多个线程安全地访问共享资源是至关重要的。为实现这一目标&#xff0c;Java提供了多种同步机制&#xff0c;其中synchronized、volatile和ReentrantLock是最常用的几种。下面&#xff0c;我们将从技术难点、面试官关注点、回答吸引力以及代码举…

如何用家政服务小程序源码系统 快速搭建家政自己接单的软件?

随着移动互联网的快速发展&#xff0c;线上预约服务已成为家政行业的新趋势。然而&#xff0c;许多家政企业面临着信息不透明、服务质量参差不齐、管理效率低下等问题。家政服务小程序系统&#xff0c;可以帮助商家快速搭建自己的接单软件&#xff0c;提升服务效率&#xff0c;…

嵌入式学习——Linux操作系统——文件编程练习

1.使用fread和fwrite方式完成任意普通文件的拷贝功能。 模拟 文件下载 #include <stdio.h>void do_copy(FILE *fp_s,FILE *fp_d) {char buf[100] {0};int ret;while (ret fread(buf,sizeof(char),sizeof(buf),fp_s))fwrite(buf,sizeof(char),ret,fp_d); }//./a.out sr…

开源网安参编的《代码大模型安全风险防范能力要求及评估方法》发布

​代码大模型在代码生成、代码翻译、代码补全、错误定位与修复、自动化测试等方面为研发人员带来了极大便利的同时&#xff0c;也带来了对安全风险防范能力的挑战。基于此&#xff0c;中国信通院依托中国人工智能产业发展联盟&#xff08;AIIA&#xff09;&#xff0c;联合开源…

深圳比创达|EMC电磁兼容性行业:电子设备质量的“守门员”

随着科技的不断进步和电子产品的普及&#xff0c;电磁兼容性&#xff08;EMC&#xff09;问题愈发受到行业内外的高度关注。EMC作为衡量电子设备在电磁环境中能否正常工作的重要指标&#xff0c;对于保障设备稳定运行、减少电磁干扰、提升产品质量具有重要意义。 一、EMC电磁兼…

水产养殖监测系统解决方案有哪几部分

随着科技的不断进步&#xff0c;水产养殖行业也迎来了智能化、信息化的新时代。在这一背景下&#xff0c;水产养殖监测系统解决方案应运而生&#xff0c;为养殖企业提供了科学、高效的管理工具。 一、系统概述 水产养殖监测系统是通过现代传感技术、数据分析技术以及互联网通信…

微信小程序(跳转)

在微信小程序中&#xff0c;常用的跳转方式包括以下几种 1.页面跳转 可以使用wx.navigateTo、wx.redirectTo和wx.reLaunch方法实现页面的跳转。 wx.navigateTo&#xff1a;保留当前页面&#xff0c;跳转到应用内的某个页面。wx.redirectTo&#xff1a;关闭当前页面&#xff…

【每日一题】503. 下一个更大元素 II

思路&#xff08;c&#xff09; 使用单调栈的解法&#xff0c;单调栈里面存的是大于当前元素的index&#xff0c;不是直接存值。但是这个题目是一个循环数组&#xff0c;可以在后面补一段前面的内容&#xff0c;这样就可以正常遍历。将每个位置对应的结果存在map中 后面循环…

mysql的语句查询顺序、耗时分析以及查询调优技巧

在MySQL中&#xff0c;SQL查询语句的执行顺序、耗时分析以及查询调优是优化数据库性能的重要方面。以下是关于这些方面的详细解释。 1. SQL查询语句的执行顺序 虽然我们编写SQL语句的顺序通常是 SELECT -> FROM -> WHERE -> GROUP BY -> HAVING -> ORDER BY -…