UE5 SQLite笔记

开发环境:

系统: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;
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

家庭网络防御系统搭建-配置流量镜像到NDR系统

由于需要将家庭网络中的全部流量送到NDR分析系统进行分析,因此需要一个具备流量镜像功能的交换机或者路由器。在前面文章所提及的家庭网络架构中,需要一台交换机即可拷贝东西向流量以及南北向流量。当然如果家庭中的路由器或者其他设备具备交换机镜像功能…

EXCEL通过VBA字典快速分类求和

EXCEL通过VBA字典快速分类求和 汇总截图 Option ExplicitOption Explicit Sub answer3() Dim wb As Workbook Dim sht As Worksheet Set wb ThisWorkbook Set sht wb.Worksheets(2) Dim ss1 As Integer Dim ss2 As Integer Dim i As Integer Dim j As Integer j 1Dim aa()…

Moonbeam 开发工具集合:打造 Web3 开发游乐场

原文:https://moonbeam.network/blog/moonbeam-developer-tooling-ecosystem/ 作者:Moonbeam 团队 编译:OneBlock Moonbeam 一直以来都在支持以太坊和 Dotsama 生态系统中的构建者和开发者。它特别为 Solidity 开发者提供了熟悉的工具&…

vue2处理跨域问题

vue中访问springboot中的RestController中的服务 &#xff08;vue.config.js不生效-CSDN博客&#xff09; 1、创建项目 使用vue init webpack my_frontend 创建vue项目 在HelloWorld.vue文件中添加内容&#xff1a; HelloWorld.vue 文件内容&#xff1a; <template>&…

react Audio 倒计时5秒,每秒播放一次音频

文章目录 1. react 倒计时 每秒播放一次音频简单demo代码2. 问题及处理方式2.1 Audio 引入出现的报错2.2 解决方法 1. react 倒计时 每秒播放一次音频简单demo代码 import React, { useState,useRef } from react; import redBagMp3 from /branch/assets/mp3/redBag.mp3 const…

Swift:“逻辑运算子“与“比较运算符“

1. 逻辑非 ! 逻辑非运算符 ! 是用于对布尔值取反的。当操作数为 true 时&#xff0c;! 将返回 false&#xff0c;而当操作数为 false 时&#xff0c;! 将返回 true。 let isTrue true let isFalse !isTrue // isFalse 现在是 false 2. 逻辑与 && 逻辑与运算符 &a…

spring-boot之接口文档Swagger配置使用

Swagger 前后端分离 Vue SpringBoot 后端时代:前端只用管理静态页面; html> 后端。模板引擎JSP >后端是主力 前后端分离式时代: ●后端:后端控制层&#xff0c;服务层,数据访问层[后端团队] ●前端:前端控制层&#xff0c;视图层[前端团队] 。伪造后端数据&#xff0c;…

Oracle Cloud公布 | 每小时 126 亿次 SQL 数据库查询

广而告之&#xff1a;2024 年数据技术嘉年华大会将于 4 月12-13 日在北京召开&#xff0c;春暖花开之际&#xff0c;数据库行业蓬勃发展之时&#xff0c;广邀天下豪杰&#xff0c;相聚北京&#xff0c;共论数据库技术发展的创新与未来。 注册&#xff1a;https://www.modb.pro/…

链表合集(easy难度)

合并两个有序链表 双指针法 由于list1和list2都是递增的&#xff0c;可以想到用双指针法。假如当前list1这个指针指向的节点被收入完成&#xff0c;那就list1&#xff1b;如果是list2被收入&#xff0c;那就list2。 具体是list1和节点被收入还是list2的节点被收入&#xff…

Java NIO详解

一、概念 NIO, 即new io&#xff0c;也叫非阻塞io 二、NIO三个核心组件&#xff1a; Buffer数据缓冲区Channel通道Selector选择器 1、Buffer缓冲区 缓冲区本质上是一个可以存放数据的内存块&#xff08;类似数组&#xff09;&#xff0c;可以在这里进行数据写入和读取。此…

webpack项目打包console git分支、打包时间等信息 exec

相关链接 MDN toLocaleString child_process Node.js strftime 格式 代码 buildinfo.js const { execSync, exec } require("child_process"); // exec: 在 Windows 执行 bat 和 cmd 脚本// execSync 同步 // exec 异步// exec 使用方法 // exec(git show -s,…

notepad++里安装32位和64位的16进制编辑器Hex-Editor

这个16进制编辑器确实是个好东西&#xff0c;平时工作种会经常用到&#xff0c; 这是hex-editor的官网。这个里边只能下载32位的(64位的看最下边)&#xff0c;选一个合适的版本&#xff0c;我当时选的是最新的版本 https://sourceforge.net/projects/npp-plugins/files/Hex%20E…

[机器学习]练习KNN算法-曼哈顿距离

曼哈顿距离(Manhattan distance) 曼哈顿距离是指在几何空间中两点之间的距离&#xff0c;其计算方法是通过将两点在各个坐标轴上的差值的绝对值相加得到。在二维空间中&#xff0c;曼哈顿距离可以表示为两点在横纵坐标上的差值的绝对值之和&#xff1b;在三维空间中&#xff0…

物联网实战--入门篇之(三)嵌入式STM32

目录 一、Keil简介 二、工程结构 三、文件目录 四、STM32简介 五、编码风格 六、总结 一、Keil简介 Keil是一款常用的单片机开发工具&#xff0c;主要包含了编译、仿真、调试和开发界面(IDE)&#xff0c;后被ARM公司收购&#xff0c;与其MDK-ARM合并为MDK-ARM Keil软件包…

如何用 C++ 部署深度学习模型?

深度学习模型在诸多领域如图像识别、自然语言处理、语音识别等展现出强大的应用潜力。然而&#xff0c;模型训练与实际部署是两个不同的环节&#xff0c;许多开发者在使用Python进行模型训练后&#xff0c;出于性能、集成便利性或特定平台要求等因素&#xff0c;会选择使用C进行…

[机器学习]练习-KNN算法

1&#xff0e;&#x1d458;近邻法是基本且简单的分类与回归方法。&#x1d458;近邻法的基本做法是&#xff1a;对给定的训练实例点和输入实例点&#xff0c;首先确定输入实例点的&#x1d458;个最近邻训练实例点&#xff0c;然后利用这&#x1d458;个训练实例点的类的多数来…

基于单片机声音分贝采集和显示控制系统设计

**单片机设计介绍&#xff0c;基于单片机声音分贝采集和显示控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机声音分贝采集和显示控制系统设计&#xff0c;主要目标是实现声音分贝的实时采集、处理以及显示…

Java复习第十三天学习笔记(HTML),附有道云笔记链接

【有道云笔记】十三 3.29 HTML https://note.youdao.com/s/Ru3zoNqM 一、基本标签 HTML:超文本标记语言 定义页面结构 CSS&#xff1a;层叠样式表 页面显示的样式、排版 BootStrap JS: JavaScript 界面交互(动态交互、逻辑) JQuery <!DOCTYPE html> <html> &l…

[羊城杯 2020]EasySer

[羊城杯 2020]EasySer 进入页面&#xff0c;发现是ubuntuapache2&#xff0c;但是好像没啥用 尝试访问/robots.txt&#xff0c;得到 访问/star1.php/&#xff0c;查看源码&#xff0c;得到提示 一看就知道是ssrf&#xff0c;使用http://127.0.0.1/ser.php&#xff0c;得到…

阿里云CentOS7安装Flink1.17

前提条件 阿里云CentOS7安装好jdk&#xff0c;官方文档要求java 11&#xff0c;使用java 8也可以。可参 hadoop安装 的jdk安装部分。 下载安装包 下载安装包 [hadoopnode1 ~]$ cd softinstall/ [hadoopnode1 softinstall]$ wget https://archive.apache.org/dist/flink/flin…