上次搭建好环境后,想单独的开发出各个模块。首先的是数据库模块,后续还有XML文件,excel读写,插件间信号传递,线程池,数据加密等模块。把各个模块集成成一个差价,后面如果想写什么东西,直接就可以拿来调用。
数据库模块,考虑到实际项目中遇到的情况,采用单例模式设计数据库插件类DBservice。外面包装一层接口DBserviceCtrl类,只给其他插件调用的接口。
具体实现如下:DBservice.h
#pragma once
#include
#include "head.h"
#include
#include
#include
#include
#include
#include
#include
#include
namespace DBService
{
// 定义MySQL连接信息
typedef struct
{
QString server;
QString user;
QString password;
QString database;
int port;
}MySQLConInfo;
enum SQL_ERROR
{
IUIT_FAIL,
IUIT_SUCCES
};
typedef struct
{
SQL_ERROR Error_Info;
QSqlError Error_Code;
}ErrorInfo;
//饿汉式单例模式
class BIL_SHARE DbService : public QObject
{
Q_OBJECT
public:
//连接数据库
bool createConnection();
// 读取数据,返回数量
int DBSelect(const std::string& Querystr, QList& data);
// 更新数据,返回数量
int DBUpdate(const std::string& Querystr, QList & datafamt, QList & data);
//插入数据,返回数量
int DBInsert(const std::string& Querystr, QList & datafamt, QList& data);
//删除数据,返回数量
int DBDelete(const std::string& Querystr, QList & data);
// 其他操作
int Query(const std::string& Querystr);
bool DBCreateTable(QList tableList);
//获取返回信息,错误码等
void GetDBErrorInfo(ErrorInfo& errorInfo);
// 插入并获取插入的ID,针对自动递增ID
int GetInsertID(const std::string& Querystr);
public:
static DbService* Instance();
//类似Java的垃圾回收器
class GC
{
public:
~GC()
{
//释放连接和资源
if (m_dbService != NULL)
{
delete m_dbService;
m_dbService = NULL;
//关闭数据库
db.close();
}
}
static GC gc; // 用于释放单例
};
private:
DbService();
DbService(const DbService &);
//DBservice& operator=(const DBservice &);
private:
static DbService *m_dbService;
static QSqlDatabase db; //数据库连接类
static QMutex m_mutex; // 锁
private:
MySQLConInfo m_mySqlConInfo; //数据库连接信息
ErrorInfo m_ErrorInfo; //错误信息
};
}
DBservice.cpp
#include "DBservice.h"
namespace DBService
{
DbService* DbService::m_dbService = NULL;
QSqlDatabase DbService::db; //数据库连接类
QMutex DbService::m_mutex; // 锁
QMutex DbService::m_mutex1; // 锁
DbService::GC DbService::GC::gc; // 重要
DbService::DbService()
{
}
DbService* DbService::Instance()
{
//保证多线程安全,加锁
m_mutex.lock();
if (m_dbService == NULL)
{
m_mutex1.lock();
if (m_dbService == NULL)
{
m_dbService = new DbService();
}
m_mutex1.unlock();
}
m_mutex.unlock();
return m_dbService;
}
bool DbService::createConnection()
{
db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("mqtest"); //这里输入你的数据库名
db.setUserName("*****");
db.setPassword("*******"); //这里输入你的密码
if (!db.open()) {
QMessageBox::critical(0, QObject::tr("无法打开数据库"), db.lastError().databaseText(), QMessageBox::Cancel);
m_ErrorInfo.Error_Code = db.lastError();
m_ErrorInfo.Error_Info = IUIT_FAIL;
return false;
} //
return true;
}
//创建表
bool DbService::DBCreateTable(QList tableList)
{
QString qslname;
for (int i = 1; i < tableList.count() - 1; i++)
qslname += (tableList.at(i) + " VARCHAR(40),");
QString sql = tr("create table %1(" "id INT NOT NULL AUTO_INCREMENT,%2PRIMARY KEY (id));").arg(tableList.at(0)).arg(qslname);
QSqlQuery query(db);
if (!query.exec(sql))
{
m_ErrorInfo.Error_Code = query.lastError();
m_ErrorInfo.Error_Info = IUIT_FAIL;
return false;
}
return true;
}
// 读取数据,返回数量
int DbService::DBSelect(const std::string& Querystr, QList& data)
{
QString sql = tr("select * from '%1'").arg(tr("表名"));
int count = 0;
QSqlQuery query(db);
memset(&m_ErrorInfo, 0, sizeof(m_ErrorInfo));
// 使数据库支持中文
query.exec("SET NAMES 'UTF8'");
if (!query.exec(sql))
{
m_ErrorInfo.Error_Code = query.lastError();
m_ErrorInfo.Error_Info = IUIT_FAIL;
return count;
}
while (query.next())
{
data.push_back(query.value(count++).toString());
}
return count;
}
// 更新数据,返回数量 修改列名,修改内容
int DbService::DBUpdate(const std::string& Querystr, QList & datafamt, QList & data)
{
int count = 0;
QString sqlset;
for (int i = 0; i < data.count(); i++)
sqlset += "" + datafamt.at(i) + " ='" + data.at(i) + "',";
sqlset = sqlset.left(sqlset.length() - 1);
QString sql = tr("update %1 set ").arg("id") + sqlset + tr(" where id = %1").arg(sqlset);
QSqlQuery query(db);
memset(&m_ErrorInfo, 0, sizeof(m_ErrorInfo));
// 使数据库支持中文
query.exec("SET NAMES 'UTF8'");
if (!query.exec(sql))
{
m_ErrorInfo.Error_Code = query.lastError();
m_ErrorInfo.Error_Info = IUIT_FAIL;
return count;
}
count = query.size();
return count;
}
//插入数据,返回数量
int DbService::DBInsert(const std::string& Querystr, QList & datafamt, QList & data)
{
int count = 0;
QString sqlDataFamt,sqlData;
for (int i = 0; i < datafamt.count(); i++)
{
sqlDataFamt += "" + datafamt.at(i) + ",";
sqlData += "" + datafamt.at(i) + ",";
}
QString sql = tr("update INTO %1 (%2) VALUES (%3) ").arg("表名").arg(sqlDataFamt).arg(sqlData);
QSqlQuery query(db);
memset(&m_ErrorInfo, 0, sizeof(m_ErrorInfo));
// 使数据库支持中文
query.exec("SET NAMES 'UTF8'");
if (!query.exec(sql))
{
m_ErrorInfo.Error_Code = query.lastError();
m_ErrorInfo.Error_Info = IUIT_FAIL;
return count;
}
count = query.size();
return count;
}
//删除数据,返回数量
int DbService::DBDelete(const std::string& Querystr, QList & data)
{
int count = 0;
QSqlQuery query(db);
QString sql = QString("delete from %2 where id=%1").arg(data[0]).arg("表名");
memset(&m_ErrorInfo, 0, sizeof(m_ErrorInfo));
// 使数据库支持中文
query.exec("SET NAMES 'UTF8'");
if (!query.exec(sql))
{
m_ErrorInfo.Error_Code = query.lastError();
m_ErrorInfo.Error_Info = IUIT_FAIL;
return count;
}
count = query.size();
return count;
}
// 其他操作
int DbService::Query(const std::string& Querystr)
{
int count = 0;
return count;
}
//获取返回信息,错误码等
void DbService::GetDBErrorInfo(ErrorInfo& errorInfo)
{
errorInfo.Error_Code = m_ErrorInfo.Error_Code;
errorInfo.Error_Info = m_ErrorInfo.Error_Info;
}
}
接口类:DBserviceCtrl.h
#pragma once
#include "DBservice.h"
#include "head.h"
namespace DBService {
//连接数据库
bool BIL_SHARE createConnection();
// 读取数据,返回数量
int BIL_SHARE DBSelect(const std::string& Querystr, QList& data);
// 更新数据,返回数量
int BIL_SHARE DBUpdate(const std::string& Querystr, QList & datafamt, QList & data);
//插入数据,返回数量
int BIL_SHARE DBInsert(const std::string& Querystr, QList & datafamt, QList& data);
//删除数据,返回数量
int BIL_SHARE DBDelete(const std::string& Querystr, QList & data);
// 其他操作
int BIL_SHARE Query(const std::string& Querystr);
bool BIL_SHARE DBCreateTable(QList tableList);
//获取返回信息,错误码等
void BIL_SHARE GetDBErrorInfo(ErrorInfo& errorInfo);
// 插入并获取插入的ID,针对自动递增ID
//int GetInsertID(const std::string& Querystr);
}
#include "DBserviceCtrl.h"
namespace DBService {
//连接数据库
bool createConnection()
{
return DBService::DbService::Instance()->createConnection();
}
// 读取数据,返回数量
int DBSelect(const std::string& Querystr, QList& data)
{
return DBService::DbService::Instance()->DBSelect(Querystr, data);
}
// 更新数据,返回数量
int DBUpdate(const std::string& Querystr, QList & datafamt, QList & data)
{
return DBService::DbService::Instance()->DBUpdate(Querystr, datafamt, data);
}
//插入数据,返回数量
int DBInsert(const std::string& Querystr, QList & datafamt, QList& data)
{
return DBService::DbService::Instance()->DBInsert(Querystr, datafamt, data);
}
//删除数据,返回数量
int DBDelete(const std::string& Querystr, QList & data)
{
return DBService::DbService::Instance()->DBDelete(Querystr, data);
}
// 其他操作
int Query(const std::string& Querystr)
{
return DBService::DbService::Instance()->Query(Querystr);
}
bool DBCreateTable(QList tableList)
{
return DBService::DbService::Instance()->DBCreateTable(tableList);
}
//获取返回信息,错误码等
void GetDBErrorInfo(ErrorInfo& errorInfo)
{
DBService::DbService::Instance()->GetDBErrorInfo(errorInfo);
}
// 插入并获取插入的ID,针对自动递增ID
//int DBserviceCtrl::GetInsertID(const std::string& Querystr)
//{
// return m_dbService->GetInsertID(Querystr);
//}
}
3.遇到的问题
1.非常低级的错误,静态变量未初始化。。。
2.没有将该插件设置为生成.dll文件,生成后事件未添加,包含目录等信息未添加。所以在别的插件中调用时,一直报找不到的错误。
3.严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK2001 无法解析的外部符号 "public: static struct QMetaObject const DBService::DbService::staticMetaObject" (?staticMetaObject@DbService@DBService@@2UQMetaObject@@B) First E:\QT5.9\First\First\First.obj 1
错误原因是,找不到moc*****.cpp文件。在网上找了很多,都说是怎么生成moc文件等等,当时moc文件是已经生成的,所以我以为是路径的问题,在属性设置下,C/C++,链接器下都添加了对应路径。都没有用。。。
解决办法:无意间,将生成的数据类这边的moc文件复制到调用插件的生成moc文件的路径下,就编译通过 啦