UE4连接MySQL数据库总结

打包优化后的插件下载地址

🍞正在为您运送作品详情 🍞正在为您运送作品详情

https://mianbaoduo.com/o/m/author-aWiTmXFtZw==/work

1.创建C++项目Test_SQL

2.建立空插件TestMySQL

3.插件目录下新建C++的Object类MyConnectionObject

4.新建蓝图函数库的C++类SqlBlueprintFunctionLibrary

5.引入第三方库,先找到Plugins/TestMySQL/Source文件夹,创建ThirdParty文件夹

                                重要 重要 重要 目录层级关系

F:\UE4\4.27\Test_SQL\Plugins\TestMySQL\Source\ThirdParty

下载地址

 🍞正在为您运送作品详情

https://mianbaoduo.com/o/bread/Yp2WlJxx

6.添加自定义模块"ConnectorLibs",//添加自定义模块

7.选择VC++目录,配置项目所需的第三方库包含目录和库目录

8.指定插件运行的平台为Win64/32。在VS工程中找到TestMySQL.uplugin文件,设置"WhitelistPlatforms": [ "Win64"]

{
	"FileVersion": 3,
	"Version": 1,
	"VersionName": "1.0.0",
	"FriendlyName": "TestMySQL",
	"Description": "SQL",
	"Category": "Other",
	"CreatedBy": "likai",
	"CreatedByURL": "6@qq.com",
	"DocsURL": "1",
	"MarketplaceURL": "",
	"SupportURL": "1",
	"CanContainContent": false,
	"IsBetaVersion": false,
	"IsExperimentalVersion": false,
	"Installed": false,
	"Modules": [
		{
			"Name": "TestMySQL",
			"Type": "Runtime",
			"LoadingPhase": "Default",
			"WhitelistPlatforms": [
				"Win64"
			]
		}
	]
}

9.编写代码

MyConnectionObject.h文件

#pragma once
 
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
//引入mysql头文件
#include "mysql.h"
#include "MyConnectionObject.generated.h"
 
/**
 *数据库连接对象类
 */
UCLASS(BlueprintType)//声明为蓝图类型的类
class TESTMYSQL_API UMyConnectionObject : public UObject
{
	GENERATED_BODY()
private:
    //声明私有构造函数
    UMyConnectionObject();
public:
    //声明MySQL连接对象
    MYSQL* Conn;
};

 MyConnectionObject.cpp文件

 
#include "MyConnectionObject.h"
 
 
UMyConnectionObject::UMyConnectionObject()
{
	//初始化连接对象
	Conn = nullptr;
}

SqlBlueprintFunctionLibrary.h文件

// Copyright 2020 NanGongTianYi. All Rights Reserved.
 
#pragma once
 
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
//引入mysql头文件
#include "mysql.h"
//引入数据库连接对象头文件
#include "MyConnectionObject.h"
#include "SqlBlueprintFunctionLibrary.generated.h"
 
/** 一行所含数据 */
USTRUCT(BlueprintType)
struct FQueryResultRow
{
	GENERATED_BODY()
		/** 一行的数据 */
		UPROPERTY(BlueprintReadWrite, Category = "Reult Row Value")
		TArray<FString> RowValue;
};
/** 所有行所数据 */
USTRUCT(BlueprintType)
struct FQueryResultRows
{
	GENERATED_BODY()
		/** 所有行数据 */
		UPROPERTY(BlueprintReadWrite, Category = "Reult Rows Value")
		TArray<FQueryResultRow> RowsValue;
};
 
/**
 * 数据库连接类
 */
UCLASS(BlueprintType)//声明为蓝图类型
class TESTMYSQL_API USqlBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
 
	/**
	 *  连接MySQL数据库
	 * @param   Host  数据库IP地址
	 * @param   UserName  数据库用户名
	 * @param   Password  数据库密码
	 * @param   DbName  数据库名
	 * @param   Port  端口号
	 * @param   Msg  提示消息
	 * @return  UMyConnectionObject*  数据库连接对象
	 */
	UFUNCTION(BlueprintCallable, Category = "SQL Utilities")
		static UMyConnectionObject* ConnectToMySQL(FString Host, FString UserName, FString Password, FString DbName, int32 Port, FString& Msg);
 
	/**
	 *  获取数据库连接状态
	 * @param ConnObj  数据库连接对象
	 * @return bool  数据库是否连接,true为已连接
	 */
	UFUNCTION(BlueprintCallable, Category = "SQL Utilities")
		static bool GetConnectionState(UMyConnectionObject* ConnObj);
 
	/**
	 *  关闭数据库连接
	 * @param ConnObj  数据库连接对象
	 * @return bool  是否关闭成功,true为关闭成功
	 */
	UFUNCTION(BlueprintCallable, Category = "SQL Utilities")
		static bool CloseConnection(UMyConnectionObject* ConnObj);
 
	/**
	 *  向数据库中添加记录
	 * @param   ConnObj  数据库连接对象
	 * @param   SqlQuery  数据库注入语句
	 * @return  bool  注入状态
	 */
	UFUNCTION(BlueprintCallable, Category = "SQL Utilities")
		static bool InsertData(UMyConnectionObject* ConnObj, FString SqlQuery);
 
	/**
	 *  修改数据库中的记录
	 * @param   ConnObj  数据库连接对象
	 * @param   SqlQuery  数据库注入语句
	 * @return  bool  修改状态
	 */
	UFUNCTION(BlueprintCallable, Category = "SQL Utilities")
		static bool UpdateData(UMyConnectionObject* ConnObj, FString SqlQuery);
 
	/**
	 *  删除数据库中的记录
	 * @param   ConnObj 数据库连接对象
	 * @param   SqlQuery  数据库注入语句
	 * @return  bool  删除状态
	 */
	UFUNCTION(BlueprintCallable, Category = "SQL Utilities")
		static bool DeleteData(UMyConnectionObject* ConnObj, FString SqlQuery);
 
	/**
	 *  删除数据库中符合条件的记录
	 * @param   ConnObj  数据库连接对象
	 * @param   TableName  表名
	 * @param   Condition  条件
	 * @return  bool  删除状态
	 */
	UFUNCTION(BlueprintCallable, Category = "SQL Utilities")
		static bool DropData(UMyConnectionObject* ConnObj, FString TableName, FString Condition);
 
	/**
	 *  从数据库中查询数据
	 * @param ConnObj  数据库连接对象
	 * @param TableName  要查询的表名
	 * @param Condition  条件映射
	 * @param bIsAnd  条件之间的关系,默认为or
	 * @return bool  查询状态
	 */
	UFUNCTION(BlueprintCallable, Category = "SQL Utilities")
		static bool SelectData(UMyConnectionObject* ConnObj, FString TableName, TMap<FString, FString> Condition, bool bIsAnd, FQueryResultRows& Results);
 
};

SqlBlueprintFunctionLibrary.cpp文件

// Copyright 2020 NanGongTianYi. All Rights Reserved.
 
 
#include "SqlBlueprintFunctionLibrary.h"
#include "Engine.h"
#include <string>
 
UMyConnectionObject* USqlBlueprintFunctionLibrary::ConnectToMySQL(FString Host, FString UserName, FString Password, FString DbName, int32 Port, FString& Msg)
{
	//字符编码格式转换
	std::string tHost(TCHAR_TO_UTF8(*Host));
	std::string tUserName(TCHAR_TO_UTF8(*UserName));
	std::string tPassword(TCHAR_TO_UTF8(*Password));
	std::string tDbName(TCHAR_TO_UTF8(*DbName));
	//数据库连接对象创建
	UMyConnectionObject* ConnObj = NewObject<UMyConnectionObject>();
	//初始化MYSQL连接对象
	ConnObj->Conn = mysql_init(nullptr);
	//判断连接状态,并返回相应信息
	if (!mysql_real_connect(ConnObj->Conn, tHost.c_str(), tUserName.c_str(), tPassword.c_str(), tDbName.c_str(), (uint32)Port, nullptr, 0))
	{
		Msg = TEXT("连接失败!");
	}
	else
	{
		Msg = TEXT("连接成功!");
	}
	//返回数据库连接对象
	return ConnObj;
}
 
bool USqlBlueprintFunctionLibrary::GetConnectionState(UMyConnectionObject* ConnObj)
{
	if (!ConnObj)
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, TEXT("对象为空!"));
		return false;
	}
	else
	{
		//判断MYSQL连接对象是否为空
		if (ConnObj->Conn != nullptr)
		{
			return true;
		}
	}
	return false;
}
 
bool USqlBlueprintFunctionLibrary::CloseConnection(UMyConnectionObject* ConnObj)
{
	if (GetConnectionState(ConnObj))
	{
		mysql_close(ConnObj->Conn);
		//指针归位,否则会变成悬挂指针
		ConnObj->Conn = nullptr;
		ConnObj = nullptr;
		return true;
	}
	return false;
}
 
bool USqlBlueprintFunctionLibrary::InsertData(UMyConnectionObject* ConnObj, FString SqlQuery)
{
	std::string tSqlQuery(TCHAR_TO_UTF8(*SqlQuery));
	//判断连接对象是否为空
	if (!ConnObj)
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, TEXT("对象为空!"));
		return false;
	}
	//判断语句是否执行成功
	if (mysql_query(ConnObj->Conn, tSqlQuery.c_str()))
	{
		GEngine->AddOnScreenDebugMessage(-1, 8.0f, FColor::Blue, TEXT("添加失败!"));
		return false;
	}
	return true;
}
 
bool USqlBlueprintFunctionLibrary::UpdateData(UMyConnectionObject* ConnObj, FString SqlQuery)
{
	std::string tSqlQuery(TCHAR_TO_UTF8(*SqlQuery));
	//判断连接对象是否为空
	if (!ConnObj)
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, TEXT("对象为空!"));
		return false;
	}
	//判断语句是否执行成功
	if (mysql_query(ConnObj->Conn, tSqlQuery.c_str()))
	{
		GEngine->AddOnScreenDebugMessage(-1, 8.0f, FColor::Blue, TEXT("修改失败!"));
		return false;
	}
	return true;
}
 
bool USqlBlueprintFunctionLibrary::DeleteData(UMyConnectionObject* ConnObj, FString SqlQuery)
{
	std::string tSqlQuery(TCHAR_TO_UTF8(*SqlQuery));
	//判断连接对象是否为空
	if (!ConnObj)
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, TEXT("对象为空!"));
		return false;
	}
	//判断语句是否执行成功
	if (mysql_query(ConnObj->Conn, tSqlQuery.c_str()))
	{
		GEngine->AddOnScreenDebugMessage(-1, 8.0f, FColor::Blue, TEXT("删除失败!"));
		return false;
	}
	return true;
}
 
bool USqlBlueprintFunctionLibrary::DropData(UMyConnectionObject* ConnObj, FString TableName, FString CondItion)
{
	FString tSqlStr = "delete from " + TableName + " where " + CondItion;
	std::string tSqlQuery(TCHAR_TO_UTF8(*tSqlStr));
	//判断连接对象是否为空
	if (!ConnObj)
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, TEXT("对象为空!"));
		return false;
	}
	//判断语句是否执行成功
	if (mysql_query(ConnObj->Conn, tSqlQuery.c_str()))
	{
		GEngine->AddOnScreenDebugMessage(-1, 8.0f, FColor::Blue, TEXT("删除失败!"));
		return false;
	}
	return true;
}
//禁用4706警告,问题在159行
#pragma warning(push)
#pragma warning( disable : 4706 )
bool USqlBlueprintFunctionLibrary::SelectData(UMyConnectionObject* ConnObj, FString TableName, TMap<FString, FString> CondItion, bool bIsAnd, FQueryResultRows& Results)
{
	FString tSqlStr = "select * from " + TableName;
	//判断连接对象是否为空
	if (!ConnObj)
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, TEXT("对象为空!"));
		return false;
	}
	//Map 含有一个条件时
	if (CondItion.Num() == 1)
	{
		FString TempStr;
		for (TMap<FString, FString>::TIterator It = CondItion.CreateIterator(); It; ++It)
		{
			TempStr = It->Key + "=" + It->Value;
		}
		tSqlStr = tSqlStr + " where " + TempStr;
	}
	//Map 含有多个条件时
	else
	{
		FString CondItionStr = bIsAnd ? " and " : " or ";
		FString SqlStr;
		for (TMap<FString, FString>::TIterator It = CondItion.CreateIterator(); It; ++It)
		{
			FString TempStr;
			TempStr = It->Key + "=" + It->Value + CondItionStr;
			SqlStr += TempStr;
		}
		tSqlStr = tSqlStr + " where " + SqlStr;
		tSqlStr = tSqlStr.Left(tSqlStr.Len() - 4);
		GEngine->AddOnScreenDebugMessage(-1, 8.0f, FColor::Red, tSqlStr);
	}
	std::string tQueryStr(TCHAR_TO_UTF8(*tSqlStr));
	if (mysql_query(ConnObj->Conn, tQueryStr.c_str()))
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, TEXT("查询失败!"));
		return false;
	}
	//查询结果处理
	MYSQL_RES* res;
	MYSQL_ROW column;
	TArray<FString> tColumsName;
	//判断连接对象是否为空
	if (!ConnObj)
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, TEXT("对象为空!"));
	}
	res = mysql_store_result(ConnObj->Conn);
	int colums = mysql_num_fields(res);
	//处理读取出来的数据
	FQueryResultRows rRows;
	while (column = mysql_fetch_row(res))
	{
		FQueryResultRow rRow;
		for (int i = 0; i < colums; i++)
		{
			//将单行数据添加到存放单行数据的数组中
			rRow.RowValue.Add(UTF8_TO_TCHAR(column[i]));
		}
		//将多行数据添加到存放多行数据的数组中
		Results.RowsValue.Add(rRow);
	}
	//释放结果集
	mysql_free_result(res);
	return true;
}

10.打包(总结自用)

生成有错误      a.先检查文件命名是否一致

                        b.路径是否一致,尤其第三方库

哔哩哔哩对应视频教程地址

UE5_MySQL插件制作_UE4_含项目源码_插件打包_哔哩哔哩_bilibili

UE4MySQL数据库插件_哔哩哔哩_bilibili

UE4.27_MySQL插件打包测试_哔哩哔哩_bilibili

  • 5
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 39
    评论
1、本课程是一个干货课程,主要讲解如何封装服务器底层,使用Tcp/ip长连接,IDE使用vs2019 c++开发以及使用c++11的一些标准,跨平台windows和linux,服务器性能高效,单服务器压力测试上万无压力,服务器框架是经历过上线产品的验证,框架简单明了,不熟悉底层封装的人,半个小时就能完全掌握服务器框架上手写业务逻辑。2、本课程是一个底层服务器框架教程,主要是教会学员在windows或linux下如何封装一个高效的,避免踩坑的商业级框架,服务器底层使用初始化即开辟内存的技术,使用内存池,服务器运行期间内存不会溢出,非常稳定,同时服务器使用自定义哈希hashContainer,在处理新的连接,新的数据,新的封包,以及解包,发包,粘包的过程,哈希容器性能非常高效,增、删、查、改永远不会随着连接人数的上升而降低性能,增、删、查、改的复杂度永远都是恒定的O(1)。3、服务器底层封装没有使用任何第三方网络库以及任何第三方插件,自由度非常的高,出了任何BUG,你都有办法去修改,查找问题也非常方便,在windows下使用iocp,linux下使用epoll.4、讲解c++纯客户端,主要用于服务器之间通信,也就是说你想搭建多层结构的服务器,服务器与服务器之间使用socket通信。还可以使用c++客户端做压力测试,开辟多线程连接服务器,教程提供了压力测试,学员可以自己做压力测试服务器性能。5、赠送ue4和unity3d通信底层框架以及多人交互demo,登录,注册,玩家离开,同步主要是教会学员服务器与客户端如何交互。6、赠送c++连接mysql数据库框架demo,登录,注册,玩家离开数据持久化.7、服务器教程使用自定义通信协议,同时也支持protobuf,选择权在开发者自己手里,想用什么协议都可以,自由度高。8、服务器教程使用手动敲代码逐句讲解的方式开展教学课程。非喜勿喷,谢谢大家。9、服务器教程提供源码,大家可以在平台提供的地址下载或者联系我,服务器使用c++11部分标准,std::thread,条件变量,线程锁,智能指针等,需要学员具备一定c++知识,购买前请慎重考虑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

手可摘星辰0120

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值