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文件的路徑下,就編譯通過 啦

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