【ue4】【技巧】支持数据库sqlite

前言

经过这两个星期对 unreal 同志的接触

深深体会到了ue兄的恶意

本来想跟着学习的节奏记录文档

但是无奈旁边都是大牛,感觉学习节奏比以前在宿舍里喝着饮料听着音乐要快十几倍,哪还来得及写博客。。心塞

本来想等学的差不多了再回过头来补一下,但是又怕到时候会忽略很多细枝末节但又很坑的事情

所以还是做到哪就从哪写起了,

虽然说这么杂乱的顺序对于本人,强迫症十级患者,是一件十分痛苦的事情

但是也只好事急从权了,唉,生活啊。。

下载 Sqlite 源码

俗话说的好哇,巧妇难为无米之炊

我们先到这个网站去买些米回来

sqlite源码下载官链

注意别下载错了

解压之后的文件

把源码放在合适的位置

买完米,洗一洗,就可以开始炊了

第一步, 在 Engine\Source\ThirdParty\sqlite 文件夹下新建一个文件夹,也取名叫 sqlite

第二步,把我们上面的四个 .c.h 格式的文件放在 这个文件夹里

第三步,返回 Engine\Source\ThirdParty\sqlite 文件夹下,用 vs 打开 sqlite.sln, 对,我们ue必须是源码编译得到的,这一点很重要

第四步,编译我们的工程,最好把四个版本都编译了

这个时候会在 Engine\Source\ThirdParty\sqlite 下生成一个叫 lib 的文件夹,它里面是这样的

这是我们编译得到的结果,我们打开 x64

接着打开 Release

其实我们需要的就是这个文件

至此,炊里有米了

为什么这么做

做饭当然是需要菜谱的,幸运的是,我真的找到了它的菜谱(千辛万苦),所以才敢信誓旦旦地说按着上面的做就对了 (o)/

我们打开 Engine\Source\Runtime\SQLiteSupport

打开 SQLiteSupport.Build.cs

发现其内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

using System.IO;

namespace UnrealBuildTool.Rules
{
public class SQLiteSupport : ModuleRules
{
public SQLiteSupport(ReadOnlyTargetRules Target) : base(Target)
{
string PlatformName = "";
string ConfigurationName = "";

switch (Target.Platform)
{
case UnrealTargetPlatform.Win32:
PlatformName = "Win32/";
break;
case UnrealTargetPlatform.Win64:
PlatformName = "x64/";
break;

case UnrealTargetPlatform.IOS:
case UnrealTargetPlatform.TVOS:
PlatformName = "IOS/";
break;
case UnrealTargetPlatform.Mac:
PlatformName = "Mac/";
break;
case UnrealTargetPlatform.Linux:
PlatformName = "Linux/";
break;
}

switch (Target.Configuration)
{
case UnrealTargetConfiguration.Debug:
ConfigurationName = "Debug/";
break;
case UnrealTargetConfiguration.DebugGame:
ConfigurationName = "Debug/";
break;
default:
ConfigurationName = "Release/";
break;
}

string LibraryPath = "" + Target.UEThirdPartySourceDirectory + "sqlite/lib/" + PlatformName + ConfigurationName;

string LibraryFilename;
if(Target.Platform == UnrealTargetPlatform.Win32 || Target.Platform == UnrealTargetPlatform.Win64 || Target.Platform == UnrealTargetPlatform.XboxOne)
{
LibraryFilename = Path.Combine(LibraryPath, "sqlite.lib");
}
else
{
LibraryFilename = Path.Combine(LibraryPath, "sqlite.a");
}

if (!File.Exists(LibraryFilename) && !Target.bPrecompile)
{
throw new BuildException("Please refer to the Engine/Source/ThirdParty/sqlite/README.txt file prior to enabling this module.");
}

PublicIncludePaths.Add(Target.UEThirdPartySourceDirectory + "sqlite/sqlite/");

PublicDependencyModuleNames.AddRange(
new string[] {
"Core",
"DatabaseSupport",
}
);

// Lib file
PublicLibraryPaths.Add(LibraryPath);
PublicAdditionalLibraries.Add(LibraryFilename);

PrecompileForTargets = PrecompileTargetsType.None;
}
}
}

乍一看很多,但是乍几下之后,是不是有一种柳暗花明的感觉 (o)/

1
PublicIncludePaths.Add(Target.UEThirdPartySourceDirectory + "sqlite/sqlite/");

这句话就是我们要在 sqlite 文件夹下再建一个 sqlite 的原因

string PlatformName = "";string ConfigurationName = ""; 这两个变量就对应着 Win32/x64Debug/Release

1
string LibraryPath = "" + Target.UEThirdPartySourceDirectory + "sqlite/lib/" + PlatformName + ConfigurationName;

它们在这一句接起来,作为 .lib 的路径,真的是一点毛病也没有~~

见证奇迹的时刻

如果现在我说,我们可以吃饭了,似乎显示有点突兀哈,但事实确是如此,嘿嘿,生活哟!

我们来做一个测试,就用我现在正在写着的 demo

首先,我打开了我的 GameModeBase.cpp 文件,我打算在它的 BeginPlay() 函数里写一些与数据库有关的代码,这样我运行游戏的时候会立马看到效果

在这之前我要先包含一下头文件

1
#include "Runtime/SQLiteSupport/Public/SQLiteDatabaseConnection.h"

忘了一件重要的事情 -_-|||

在这之前的之前,我要打开这个项目的 Build.cs 文件

要在下面一句后面加上 SQLiteSupport

表示加上对这个 Module 的依赖

1
2
3
4
5
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG", "HeadMountedDisplay", "SQLiteSupport" });

// 因为我的 vs 有些错误提示,我尝试着在private里也加了一下
//但是错误提示还在,并没有任何效果,但是错误提示并没有影响到编译和运行
PrivateDependencyModuleNames.AddRange(new string[] { "SQLiteSupport" });

好了,言归正传,我们来看看, 呃,,不对,我要先在一个地方, 比如说 E盘根目录,建一个数据库文件,以便测试

好了,言归正传,我们来看看在 BeginPlay 里写的测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void ADGameGameModeBase::BeginPlay() {
Super::BeginPlay();
//... 一些与此无关的代码

// datebase test
FSQLiteDatabase my_db;
if(my_db.Open(TEXT("E:/mydb.db"), nullptr, nullptr)) {
int id = 1;
FString pw = TEXT("'123'");
FString name = TEXT("'dua'");
FString sql = FString::Printf(TEXT("insert into user (user_id, user_pw, user_name) values (%d, %s, %s)"), id, *pw, *name);
GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Green, sql);
if(!my_db.Execute(*(sql))) {
GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Green, "no");
}
else GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Green, "good");

}

编译并运行,进入到pie中去,我们会看到

再看看我们的数据库

感人!

千辛万苦历经磨难,折腾了一天,终于可以吃饭了

我遇到的坑

一开始编译提示找不到 .lib 文件

解决方法 -- 多编译几次

真正的解决方法 -- 尝试重新编译一下 ue4

提示 预置的 #include xxx.h 文件应该放在 .cpp 文件的第一个

解决方法 -- 打开 Engine\Source\Runtime\SQLiteSupport\Private 下的 SQLiteDatabaseConnection.cpp 文件 和 SQLiteResultSet.cpp 文件

分别将它们的 .h 文件放在第一个去 include

如果 sql 语句中有字符串,不要忘了用 单引号 ‘xxx’ 包含

结语

写到这里,才发现原来我是前台程序猿,不需要关心后台数据库的,,心塞

但是总的来说,今天还是愉快而充实的一天,起码知道了如果使用ue的第三方库

也算是不虚此行(略显牵强的自我安慰-_-|||)

最后总结一下

生命在于折腾,ue在于要命

远离ue, 珍爱生命