UE4学习笔记--连接MySQL数据库(C++)

UE4学习笔记--连接MySQL数据库


我个人是个比较水的人,在学校没好好学程序,不误正业的玩建模,现在美术和程序都不行……想想还是重新认真学程序吧,先从记笔记开始,话说我还是第一次写博客……
我是跟着几位大佬的博客做的,记录一下自己的问题,以免以后忘记.
大佬的链接如下:
https://blog.csdn.net/jack0596_cn/article/details/52387890.
https://blog.csdn.net/boonti/article/details/84255014.
UE4连接MySQL数据库步骤

  1. 首先搞到MySQL的连接文件 MySQL Connector.C 6.1(在C:\Program Files \MySQL文件下,注意要看好自己的程序需要的是32位的库还是64位的库)
  2. 然后到项目文件夹下新建文件夹ThirdParty,并将连接文件复制到ThirdParty文件夹下,将连接文件的文件名中的空格全部删去
  3. 将lib文件夹下的dll文件放到项目文件夹下的Binaries文件夹
  4. 常规的C++添加第三方库的方法对虚幻不是很适用,可能会出现一系列问题,所以要在插件模块的.build.cs下添加以下代码
using UnrealBuildTool;
using System.IO;
public class MySQLUtility : ModuleRules
{
   public MySQLUtility(ReadOnlyTargetRules Target) : base(Target)
   {
   	PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
   	


   	PublicIncludePaths.AddRange(
   		new string[] {
   			// ... add public include paths required here ...
   		}
   		);
   			
   	
   	PrivateIncludePaths.AddRange(
   		new string[] {
   			// ... add other private include paths required here ...
   		}
   		);
   		
   	
   	PublicDependencyModuleNames.AddRange(
   		new string[]
   		{
   			"Core",
   			// ... add other public dependencies that you statically link with here ...
   		}
   		);
   		
   	
   	PrivateDependencyModuleNames.AddRange(
   		new string[]
   		{
   			"CoreUObject",
   			"Engine",
   			"Slate",
   			"SlateCore",
               //"HeadMountedDisplay",
   			// ... add private dependencies that you statically link with here ...	
   		}
   		);
   	
   	
   	DynamicallyLoadedModuleNames.AddRange(
   		new string[]
   		{
   			// ... add any modules that your module loads dynamically here ...
   		}
   		);
//需要增加的代码
       string ModulePath = ModuleDirectory; //获取本.build.cs文件的路径
       string ThirdPartyPath = Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/"));//获取第三方库文件的路径。
       string MySQLConnectorLibraryPath = ThirdPartyPath + "MySQLConnectorC8/lib64/";//获取连接文件的路径。
       string MySQLConnectorIncludePath = ThirdPartyPath + "MySQLConnectorC8/include/jdbc/";//获取第三方库的头文件路径。
       string MySQLConnectorImportLibraryName = Path.Combine(MySQLConnectorLibraryPath, "vs14/mysqlcppconn.lib");//获取第三方库的连接文件的路径。
       string MySQLConnectorDLLName = Path.Combine(MySQLConnectorLibraryPath, "mysqlcppconn-7-vs14.dll");//获取第三方动态链接库文件的路径。

       if (!File.Exists(MySQLConnectorImportLibraryName))
       {
           throw new BuildException(string.Format("{0} could not be found.", MySQLConnectorImportLibraryName));//如果找不到文件,编译器报错!
       }

       if (!File.Exists(MySQLConnectorDLLName))
       {
           throw new BuildException(string.Format("{0} could not be found.", MySQLConnectorDLLName));
       }

       PublicIncludePaths.Add(MySQLConnectorIncludePath);//注册第三方库头文件的路径。
       PublicLibraryPaths.Add(MySQLConnectorLibraryPath);//注册第三方库连接文件的路径。
       PublicAdditionalLibraries.Add(MySQLConnectorImportLibraryName);//注册第三方库的连接文件。
       //PublicDelayLoadDLLs.Add(MySQLConnectorDLLName);
       bEnableUndefinedIdentifierWarnings = false;
   }
}

  1. 在工程所对应的.build.cs的文件中加上bEnableUndefinedIdentifierWarnings = false;就不会报没有将“某某某”定义为预处理器宏,用“0”替换“#if/#elif”的错误了
  2. 在打包时可能会报平台的错误,这需要去插件的.uplugin文件下添加白名单代码
{
	"FileVersion": 3,
	"Version": 1,
	"VersionName": "1.0",
	"FriendlyName": "MySQLUtility",
	"Description": "",
	"Category": "Other",
	"CreatedBy": "",
	"CreatedByURL": "",
	"DocsURL": "",
	"MarketplaceURL": "",
	"SupportURL": "",
	"CanContainContent": true,
	"IsBetaVersion": false,
	"Installed": false,
  "Modules": [
    {
      "Name": "MySQLUtility",
      "Type": "Runtime",
      "LoadingPhase": "Default",
      "WhitelistPlatforms": [
        "Win64",
        "Win32",
        "HTML5"
      ]
    }
  ]
}

测试代码如下 MyBlueprintFunctionLibrary.h文件

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "mysql_connection.h"
#include "mysql_driver.h"
#include "cppconn/resultset.h"
#include "cppconn/statement.h"
#include "MySQLConnectObject.h"
#include "MyBlueprintFunctionLibrary.generated.h"

using namespace sql;
/**
 * 
 */

USTRUCT()
struct FSQLCon
{
	GENERATED_USTRUCT_BODY()
public:
	
	Connection* con;
};

UCLASS()
class MYSQLUTILITY_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

	UFUNCTION(BlueprintCallable, Category = "MySQL")
	static UMySQLConnectObject* ConnectMySQL(FString Username,FString Password, FString DataBase);
	UFUNCTION(BlueprintCallable, Category = "MySQL")
	static UMySQLConnectObject* exeQueryMySQL(UMySQLConnectObject* con,FString SQL);
	UFUNCTION(BlueprintCallable, Category = "MySQL")
	static void CloseMySQL(UMySQLConnectObject* con);
		

};

测试代码如下 MyBlueprintFunctionLibrary.cpp文件

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyBlueprintFunctionLibrary.h"
#include "Engine/Engine.h"

UMySQLConnectObject* UMyBlueprintFunctionLibrary::ConnectMySQL(FString Username, FString Password,FString DataBase)
{		
	Driver *driver;
	Connection *con=NULL;
	if (GEngine)
	{

		try
		{
			driver = get_driver_instance();
			if (Username.IsEmpty() || Password.IsEmpty() || DataBase.IsEmpty())
			{
				con = driver->connect("tcp://127.0.0.1:3306", "root", "MySQL125799");
				con->setSchema("asdf");
			}
			else
			{
				con = driver->connect("tcp://127.0.0.1:3306", TCHAR_TO_UTF8(*Username), TCHAR_TO_UTF8(*Password));
				con->setSchema(TCHAR_TO_UTF8(*DataBase));
			}
		}
		catch (SQLException &e)
		{
			//cout << "ERROR: SQLException in ";
			GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR: SQLException in MyBlueprintFunctionLibrary")));
			GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR:")) + FString(e.what()));
			if (e.getErrorCode() == 1047) {
				/*
				Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR)
				Message: Unknown command
				*/
				GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("\nYour server does not seem to support Prepared Statements at all. ")));
			}
		}
		catch (std::runtime_error &e)
		{
			GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR: runtime_error in ")) + TEXT(__FILE__));
			GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR:")) + FString(e.what()));
		}		
	}
	UMySQLConnectObject* tmp = NewObject<UMySQLConnectObject>();
	tmp->con = con;
	return tmp;
}



UMySQLConnectObject* UMyBlueprintFunctionLibrary::exeQueryMySQL(UMySQLConnectObject* con, FString SQL)
{

	Statement *stmt = NULL;
	ResultSet *res = NULL;
	
	if (con->con==NULL)
	{
		return con;
	}
	
	if (con==NULL||SQL.IsEmpty())
	{
	
			if (con->con)
	{
		stmt = con->con->createStatement();
					try
					{
					
						res = stmt->executeQuery("SELECT * from goods");
					}
					catch (SQLException &e)
					{
						//cout << "ERROR: SQLException in ";
						GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR: SQLException in MyBlueprintFunctionLibrary")));
						GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR:")) + FString(e.what()));
						if (e.getErrorCode() == 1047) {
							/*
							Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR)
							Message: Unknown command
							*/
							GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("\nYour server does not seem to support Prepared Statements at all. ")));
						}
						return con;
					}
					catch (std::runtime_error &e)
					{
						GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR: runtime_error in ")) + TEXT(__FILE__));
						GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR:")) + FString(e.what()));
						return con;
					}
					// 标准sql语句
					while (res->next())
					{
						GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Red, FString(TEXT("gid为 ")) + UTF8_TO_TCHAR(res->getString("gid").c_str()));
					}
	}
	
			delete res;
			delete stmt;
	}
	else
	{
		stmt = con->con->createStatement();
		try
		{
			res = stmt->executeQuery(TCHAR_TO_UTF8(*SQL));
		}
		catch (SQLException &e)
		{
			//cout << "ERROR: SQLException in ";
			GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR: SQLException in MyBlueprintFunctionLibrary")));
			GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR:")) + FString(e.what()));
			if (e.getErrorCode() == 1047) {
				/*
				Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR)
				Message: Unknown command
				*/
				GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("\nYour server does not seem to support Prepared Statements at all. ")));
			}
			return con;
		}
		catch (std::runtime_error &e)
		{
			GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR: runtime_error in ")) + TEXT(__FILE__));
			GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString(TEXT("ERROR:")) + FString(e.what()));
			return con;
		}
		// 标准sql语句
		while (res->next())
		{
			GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Red, FString(TEXT("gid为 ")) + UTF8_TO_TCHAR(res->getString("gid").c_str()));
		}

		delete res;
		delete stmt;
	}
        return con;
}

void UMyBlueprintFunctionLibrary::CloseMySQL(UMySQLConnectObject* con)
{
	//delete res;
	//delete stmt;
	
	if (con->con)
	{
		con->con->close();
	}
}


测试代码如下 MySQLConnectObject.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "mysql_connection.h"
#include "mysql_driver.h"
#include "cppconn/resultset.h"
#include "cppconn/statement.h"
#include "MySQLConnectObject.generated.h"

/**
 * 
 */
using namespace sql;


UCLASS(BlueprintType)
class MYSQLUTILITY_API UMySQLConnectObject : public UObject
{
	GENERATED_BODY()
public:

	Connection* con;
};

测试代码如下MySQLConnectObject.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "MySQLConnectObject.h"



打包的时候发现不能使用try catch语句,这是因为虚幻默认禁用,想要开启需要在.build.cs下添加一句
bEnableExceptions = true;
其他bool变量的作用可以查看源码的ModuleRules类的成员变量的注释

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
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++知识,购买前请慎重考虑。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值