UE5 SQLite笔记

news2024/11/26 23:30:06

开发环境:

系统:Windows 10 64 bit
引擎:Unreal Engine 5.1.1
IDE:JetBrains Rider 2023.2.1
语言:C++
工具:DB Browser for SQLite

 SQLite数据类型:

    //INTEGER	TEXT	BLOB	REAL	NUMERIC
	/*
		integer 				--->整数,可以是1、2、3、4、6或8个字节,SQLite会根据数值大小自动调整。
		real 					--->实数(浮点数),一律使用8个字节存储
		text 					--->文本,最大支持长度为1,000,000,000个字符的单个字符串
		blob 					--->二进制对象,最大支持长度为1,000,000,000个字节
		null 					--->没有值
		char(size)  			--->固定长度的字符串,size规定字符串的长度
		varchar(size) 			--->可变长度的字符串,size规定字符串的最大字符个数
	*/

启用插件:

添加插件模块引用:"SQLiteCore","SQLiteSupport"

// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class PakFramework : ModuleRules
{
	public PakFramework(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG","SQLiteCore","SQLiteSupport"});

		// Uncomment if you are using Slate UI
		//PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore", "InputDevice"});
		
		// Uncomment if you are using online features
		// PrivateDependencyModuleNames.Add("OnlineSubsystem");

		// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
	}
}

示例代码:

【ASQLiteManager.h】

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "SQLiteDatabaseConnection.h"
#include "SQLiteManager.generated.h"

UCLASS()
class PAKFRAMEWORK_API ASQLiteManager : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	ASQLiteManager();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:
	// Called every frame
	virtual void Tick(float DeltaTime) override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

private:
	FSQLiteDatabaseConnection DBConnection;
	bool bIsOpened = false;
public:
	bool OpenDB(const FString& FileFullPath,const FString& UserName = TEXT(""),const FString& Password = TEXT(""));
	bool CloseDB();
	bool ExecSql(const TCHAR* InStatement);
	bool ExecSql(const TCHAR* InStatement, FDataBaseRecordSet*& RecordSet);
}

【ASQLiteManager.cpp】

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


#include "SQLiteManager.h"

#include "MyFramework/AOT/Runtime/CoreKits/LogKit.h"


// Sets default values
ASQLiteManager::ASQLiteManager()
{
	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
}

// Called when the game starts or when spawned
void ASQLiteManager::BeginPlay()
{
	Super::BeginPlay();

	const FString DBFileFullPath = TEXT("D:/_DB/DB_G005.db");
	if(OpenDB(DBFileFullPath))
	{
		/*
		//【1.创建数据表】
		if(ExecSql(TEXT("create table table_name(id integer,name text,age integer);") ))
		{
			ULogKit::I(__FUNCTION__,TEXT("成功生成表格!!!"));
		}
		else
		{
			ULogKit::E(__FUNCTION__,TEXT("生成表格失败!!!"));
		}
		*/

		/*
		//【2.检查数据表是否存在】
		FDataBaseRecordSet* ResultSet;
		if(ExecSql(TEXT("select * from sqlite_master where type = 'table' and name = 'table_name';"),ResultSet))
		{
			const int32 RecordCount = ResultSet->GetRecordCount();
			if(RecordCount > 0)
			{
				ULogKit::I(__FUNCTION__,TEXT("数据表 存在!!!"));
			}
			else
			{
				ULogKit::E(__FUNCTION__,TEXT("数据表 不存在 1 !!!"));
			}
			//【注意】
			//此处必须删除FDataBaseRecordSet对象,其为new方式生成对象-->[FSQLiteDatabaseConnection.cpp]-->RecordSet = new FSQLiteResultSet(MoveTemp(PreparedStatement));
			//否则CloseDB()会失败,退出程序时抛出异常:"Destructor called while an SQLite database was still open. Did you forget to call Close?"
			delete ResultSet;
			ResultSet = nullptr;
		}
		else
		{
			ULogKit::E(__FUNCTION__,TEXT("数据表 不存在 2 !!!"));
		}
		*/
		
		/*
		//【3.插入表字段】
		if(ExecSql(TEXT("alter table table_name add column age2 integer;")))
		{
			ULogKit::I(__FUNCTION__,TEXT("插入表字段 成功!!!"));
		}
		else
		{
			ULogKit::E(__FUNCTION__,TEXT("插入表字段 失败!!!"));
		}
		*/
		
		/*
		//【4.删除表】
		if(ExecSql(TEXT("drop table table_name;")))
		{
			ULogKit::I(__FUNCTION__,TEXT("删除表 成功!!!"));
		}
		else
		{
			ULogKit::E(__FUNCTION__,TEXT("删除表 失败!!!"));
		}
		*/

		/*
		//【5.1.数据-增加行】
		if(ExecSql(TEXT("insert into table_name values(1,\"张三\",18,19);")))//不指定列字段
		{
			ULogKit::I(__FUNCTION__,TEXT("增加行 成功!!!"));
		}
		else
		{
			ULogKit::E(__FUNCTION__,TEXT("增加行 失败!!!"));
		}
		//【5.2.数据-增加行】
		if(ExecSql(TEXT("insert into table_name(name ,age) values(\"李四\",18);")))//指定列字段
		{
			ULogKit::I(__FUNCTION__,TEXT("增加行 成功!!!"));
		}
		else
		{
			ULogKit::E(__FUNCTION__,TEXT("增加行 失败!!!"));
		}
		*/
		
		/*
		//【6.数据-删除行】
		if(ExecSql(TEXT("delete from table_name where id=1;")))
		{
			ULogKit::I(__FUNCTION__,TEXT("删除行 成功!!!"));//若删除不存在项,也会返回true
		}
		else
		{
			ULogKit::E(__FUNCTION__,TEXT("删除行 失败!!!"));
		}
		*/

		/*
		//【7.数据-更新行】
		if(ExecSql(TEXT("update table_name set name=\"王五\",age=38 where id=1;")))
		{
			ULogKit::I(__FUNCTION__,TEXT("更新行 成功!!!"));//删除不存在项,也会返回true
		}
		else
		{
			ULogKit::E(__FUNCTION__,TEXT("更新行 失败!!!"));
		}
		*/

		
		//【8.数据-查询】
		FDataBaseRecordSet* ResultSet;
		if(DBConnection.Execute(TEXT("select * from tablename"),ResultSet))
		{
			FDataBaseRecordSet::TIterator itor(ResultSet);
			//通过get获得数据
			while (itor) {
				int32 Id = itor->GetInt(TEXT("id"));
				FString Name = itor->GetString(TEXT("name"));
				int32 Age = itor->GetInt(TEXT("age"));
				ULogKit::I(__FUNCTION__,
					TEXT("id = ")+FString::FromInt(Id)
					+TEXT(" ; name = ")+Name
					+TEXT(" ; age = ")+FString::FromInt(Age));
				++itor;
			}
			//【注意】
			//此处必须删除FDataBaseRecordSet对象,其为new方式生成对象-->[FSQLiteDatabaseConnection.cpp]-->RecordSet = new FSQLiteResultSet(MoveTemp(PreparedStatement));
			//否则CloseDB()会失败,退出程序时抛出异常:"Destructor called while an SQLite database was still open. Did you forget to call Close?"
			delete ResultSet;
			ResultSet = nullptr;
		}
		
	}
	else
	{
		ULogKit::E(__FUNCTION__,TEXT("无法打开DB!!!"));
	}
}

// Called every frame
void ASQLiteManager::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

void ASQLiteManager::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	CloseDB();
}

bool ASQLiteManager::OpenDB(const FString& FileFullPath,const FString& UserName,const FString& Password)
{
	if(IsDatabaseExists(FileFullPath))
	{
		if(DBConnection.Open(*FileFullPath,nullptr,nullptr))
		{
			bIsOpened = true;
		}
		else
		{
			bIsOpened = false;
		}
	}
	else
	{
		bIsOpened = false;
	}
	return bIsOpened;
}

bool ASQLiteManager::CloseDB()
{
	if(bIsOpened)
	{
		DBConnection.Close();
		return true;
	}
	else
	{
		return false;
	}
}

bool ASQLiteManager::ExecSql(const TCHAR* InStatement)
{
	if(bIsOpened)
	{
		return DBConnection.Execute(InStatement);
	}
	else
	{
		return false;
	}
}

bool ASQLiteManager::ExecSql(const TCHAR* InStatement, FDataBaseRecordSet*& RecordSet)
{
	if(bIsOpened)
	{
		return DBConnection.Execute(InStatement,RecordSet);
	}
	else
	{
		return false;
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1561023.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Pilotfish扩展Sui执行能力

Pilotfish第一个多机智能合约执行引擎,使Sui网络的验证节点可以利用多台机器,并在负载增加时自动扩展以执行更多的交易。这一目标实现不会影响可靠性或功能完整性。 Pilotfish可以从内部执行机器的故障中恢复,并支持Sui的全面动态操作。其流…

TCP粘包是怎么回事,如何处理?

还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,ech…

Wafer的T7 Code是什么,怎么来的

1、T7 Code是什么 在半导体Cim系统中,waferstart 业务需要支持 Sorter 读取 Wafer 的 T7 Code,与 MES 的 Wafer ID 进行绑定,以便向 前追溯 Wafer 历史,那么问题来了,T7code 是什么 Wafer的T7 Code是一种背面刻号,用于标识双面抛光的晶圆。这种标记采用二维矩阵代码符号,…

海外问卷调查保姆级教程,看完这篇就不用再找别的了

大家好,我是橙河老师,最近很多小伙伴在问海外问卷调查怎么做?这篇文章就从环境搭建到做问卷的过程,全部展示给大家,希望大家能够学会。 这个是保姆级教程了,争取一次就把大家教会,多看教程&…

Docker服务

任务描述:请采用podman,实现有守护程序的容器应用。 (1)在linux2上安装docker-ce,导入rocky镜像。 (2)创建名称为skills的容器,映射本机的8000端口到容器的80端口,在容…

Object类-equals方法

细节:1、equals方法默认先比较两个对象的地址是否相同(即两个对象是否是同一个对象),如果是同一个对象返回true;如果不是同一个对象,返回false。 2、子类中重写父类的equals方法后,比较的是两个…

如何算通过了PMP考试?

一般在PMP考试结束后的6-8周便可以在PMI网站查询到成绩,或者查看PMI发送给考生的成绩邮件。如果成绩上显示“PASS”就是通过,“FAIL”就是没通过。 需要注意的是你看到的成绩不是直接的分数,而是用A\T\B\N表示的,即Above Target(…

2024银行业最新数字化转型的方法与路径

银行业数字化转型是一场由思想到行动、由顶层到基层、由内部到外部的深刻变革, 需要科学方法论的指导。在推动体系性重塑、开放生态建设、业务科技融合、基础设施升 级以及体制机制变革等探索和实践中,银行业逐步形成从顶层设计到数字化能力建设&#xf…

JavaEE 初阶篇-深入了解多线程安全问题(指令重排序、解决内存可见性与等待通知机制)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 指令重排序概述 1.1 指令重排序主要分为两种类型 1.2 指令重排序所引发的问题 2.0 内存可见性概述 2.1 导致内存可见性问题主要涉及两个方面 2.2 解决内存可见性问…

C语言----预处理(详解)

好了书接上回。我在讲编译与链接的时候写过宏和条件建议。我说会在下一篇博客中讲解,那么来了。今天我们来详细的讲讲预处理。宏与条件编译也在其中,那么我们现在就来好好会会这个预处理吧。 预定义符号 关于预定义符号,我暂时只知道几个。并…

安装kubesphere的 devops 插件报错

安装kubesphere的 devops 插件报错: ks-minio 报错: TASK [common : Kubesphere | Check minio] *************************************** changed: [localhost]TASK [common : Kubesphere | Deploy minio] ************************************** fa…

期货开户分析的三个基本要素

我常用的交易系统为概率分析系统,具备的三个基本要素与三个基本原则: 1、行情研判规则。这是最基础的,你必须首先用交易系统对行情有一个正确的判断。 2、进出场规则。在进出场规则当中,我个人更看重出场规则。因为实际上&#…

腾讯云容器与Serverless的融合:探索《2023技术实践精选集》中的创新实践

腾讯云容器与Serverless的融合:探索《2023技术实践精选集》中的创新实践 文章目录 腾讯云容器与Serverless的融合:探索《2023技术实践精选集》中的创新实践引言《2023腾讯云容器和函数计算技术实践精选集》整体评价特色亮点分析Serverless与Kubernetes的…

什么是智慧公厕?智慧城市下的智慧公厕有什么功能和特点?

随着科技的不断进步和城市化的加快发展,智慧城市已经成为我们生活中的一部分。而在智慧城市的建设中,智慧公厕作为城市基础设施的重要组成部分发挥着重要的作用。那么什么是智慧公厕?智慧公厕是针对公共厕所的日常使用、运行、管理、运营等过…

数据科学薪酬分析项目

注意:本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 ([www.aideeplearning.cn]) 项目简介 《数据科学薪酬分析》是一个全面的分析项目,旨在探索和解释数据科学领域的薪酬趋势。通过分析607份不同工作年份、经验水平…

跑通飞浆平台的MTMCT 跨镜跟踪示例

想跑通飞浆平台的MTMCT跨镜跟踪示例,真的是难上加难啊! 改了几处代码,可以顺利跑通了,特此记录: 第一处:不要拉主线的代码,改成 !git clone https://gitee.com/paddlepaddle/PaddleDetection…

C++教学——从入门到精通 7.if,else语句

有一个商人在街头衣服,每次卖完都不知道自己是赚了还是亏了,他想请你帮他算一算他一天赚了多少还是亏了多少 首先我们知道商人每天卖5件衣服,利润售价-成本,那么我们该编一个怎么样的程序呢? 我们来学一个新的语句—…

四氟进样器耐腐蚀耐高温可灵活加工PTFE材质含氟塑料注射器

四氟注射器用于抽取或者注入气体或者液体,四氟注射器由前端带有小孔的针筒以及与之匹配的活塞芯杆组成,用来将少量的液体或其注入到其它方法无法接近的区域或者从那些地方抽出,在芯杆拔出的时候液体或者气体从针筒前端小孔吸入,在…

MyBatis 参数重复打印的bug

现象 最近有个需求,需要在mybatis对数据库进行写入操作的时候,根据条件对对象中的某个值进行置空,然后再进行写入,这样数据库中的值就会为空了。 根据网上查看的资料,选择在 StatementHandler 类执行 update 的时候进…

虚拟内存到物理地址的映射,是CPU做的,还是操作系统做的?

虚拟地址到物理地址的转换,是CPU实现得,具体来说,就是CPU的内存管理单元 (Memory Management Unit, MMU)实现的。 为了加速地址翻译的 过程,现代CPU都引入了转址旁路缓存(Translation Loopasid…