QT5+VS2017+Mysql5.5(二)-数据库模块独立插件

1.前言

上次搭建好环境后,想单独的开发出各个模块。首先的是数据库模块,后续还有XML文件,excel读写,插件间信号传递,线程池,数据加密等模块。把各个模块集成成一个差价,后面如果想写什么东西,直接就可以拿来调用。

2.内容

数据库模块,考虑到实际项目中遇到的情况,采用单例模式设计数据库插件类DBservice。外面包装一层接口DBserviceCtrl类,只给其他插件调用的接口。

具体实现如下:DBservice.h

#pragma once

#include <QtWidgets/QMainWindow>
#include "head.h"
#include <QSqlDatabase>
#include <QMessageBox>
#include <QSqlQuery>
#include <QSqlError>
#include <QList>
#include <string>
#include <QMutex>
#include <QVariant>

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<QString>& data);
		 // 更新数据,返回数量
		 int DBUpdate(const std::string& Querystr, QList<QString> & datafamt, QList<QString> & data);
		 //插入数据,返回数量
		 int DBInsert(const std::string& Querystr, QList<QString> & datafamt, QList<QString>& data);
		 //删除数据,返回数量
		 int DBDelete(const std::string& Querystr, QList<QString> & data);
		 // 其他操作
		 int Query(const std::string& Querystr);   

		 bool DBCreateTable(QList<QString> 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<QString> 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<QString>& 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<QString> & datafamt, QList<QString> & 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<QString> & datafamt, QList<QString> & 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<QString> & 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<QString>& data);
		// 更新数据,返回数量
		int BIL_SHARE DBUpdate(const std::string& Querystr, QList<QString> & datafamt, QList<QString> & data);
		//插入数据,返回数量
		int BIL_SHARE DBInsert(const std::string& Querystr, QList<QString> & datafamt, QList<QString>& data);
		//删除数据,返回数量
		int BIL_SHARE DBDelete(const std::string& Querystr, QList<QString> & data);
		// 其他操作
		int BIL_SHARE Query(const std::string& Querystr);

		bool BIL_SHARE DBCreateTable(QList<QString> 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<QString>& data)
	{
		return DBService::DbService::Instance()->DBSelect(Querystr, data);
	}
	// 更新数据,返回数量
	int DBUpdate(const std::string& Querystr, QList<QString> & datafamt, QList<QString> & data)
	{
		return DBService::DbService::Instance()->DBUpdate(Querystr, datafamt, data);
	}
	//插入数据,返回数量
	int DBInsert(const std::string& Querystr, QList<QString> & datafamt, QList<QString>& data)
	{
		return DBService::DbService::Instance()->DBInsert(Querystr, datafamt, data);
	}
	//删除数据,返回数量
	int DBDelete(const std::string& Querystr, QList<QString> & data)
	{
		return DBService::DbService::Instance()->DBDelete(Querystr, data);
	}
	// 其他操作
	int Query(const std::string& Querystr)
	{
		return DBService::DbService::Instance()->Query(Querystr);
	}

	bool DBCreateTable(QList<QString> 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文件的路径下,就编译通过 啦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章