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;
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UniApp是一个基于Vue.js框架的跨平台开发工具,它可以同时开发和编译生成iOS、Android、H5等多个平台的应用。H5是指基于HTML5技术开发的网页应用。SQLite是一种轻量级数据库引擎,支持在设备上进行本地存储和操作数据。 在UniApp中使用SQLite可以实现在H5应用中进行本地数据存储和管理。UniApp内置了一个插件uni.sqlite,该插件封装了SQLite的常用操作方法,包括数据库的创建、表的创建、数据的增删改查等。 具体步骤如下: 1. 在UniApp项目的manifest.json文件中配置sqlite插件,确保插件已经安装。 2. 在需要使用SQLite的页面中引入uni.sqlite插件。 3. 使用uni.sqlite的openDatabase方法创建或打开数据库文件,指定数据库名称和版本号。 4. 使用executeSql方法执行SQL语句,包括创建表、插入数据、更新数据等操作。 5. 使用selectSql方法进行查询数据操作,获取返回的结果。 6. 在操作完成后,使用closeDatabase方法关闭数据库连接。 通过UniApp H5开发使用SQLite可以实现许多应用场景,如离线缓存数据、本地日志记录、提供离线功能等。在H5应用中使用SQLite可以使应用更加灵活、高效,并且可以在不联网的情况下继续提供一些核心功能。 总结而言,UniApp H5和SQLite的结合可以实现在H5应用中进行本地数据存储和管理,提高应用性能和用户体验。这是一个非常有价值和实用的技术组合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值