使用Json作为数据库

使用 JSON 文件作为数据库来存储游戏数据是一个简单的实现方式,尤其对于小型项目或原型开发非常有效。虽然 JSON 文件本身不具备数据库的高级功能(如事务、索引、并发访问等),但你仍然可以通过 TypeScript 实现增删改查(CRUD)操作。以下是如何使用 JSON 文件来实现这些功能的具体步骤。

1. 准备工作

首先,确保你已经有一个 JSON 文件来存储数据,假设它存储在 gameData.json 文件中,并且数据格式如下:

{"nodes": [{"id": 1,"name": "Hero","description": "The brave hero of the story.","status": "alive"},{"id": 2,"name": "Villain","description": "The evil villain who seeks to conquer the world.","status": "alive"}]
}

2. 操作 JSON 文件

为了实现增删改查操作,我们需要能够读取和修改 JSON 文件。通常使用 fs(文件系统模块)来读取和写入文件。我们还需要一个函数来将数据转换为 JSON 格式,以便于保存。

安装必要的依赖

npm install fs-extra

fs-extra 是一个比 fs 更强大的文件操作库,支持异步和同步的 API,还提供了一些额外的便利方法,如 json() 来处理 JSON 文件。

3. 实现增删改查操作

3.1 增加节点(Create)

要向 JSON 文件中添加新节点,你需要先读取当前数据,更新它,然后写回文件。

import * as fs from 'fs-extra';interface GameNode {id: number;name: string;description: string;status?: string;additionalInfo?: any;
}interface GameData {nodes: GameNode[];
}// 读取 JSON 文件
async function readData(): Promise<GameData> {const data = await fs.readJson('gameData.json');return data;
}// 写入 JSON 文件
async function writeData(data: GameData): Promise<void> {await fs.writeJson('gameData.json', data, { spaces: 2 });
}// 增加节点
async function addNode(newNode: GameNode) {const data = await readData();data.nodes.push(newNode);await writeData(data);console.log('Node added successfully!');
}// 示例:增加一个新的节点
const newNode: GameNode = {id: 3,name: "Potion",description: "A health potion that restores health.",status: "available",
};addNode(newNode);

3.2 删除节点(Delete)

删除节点时,我们根据节点的 id 找到它并删除。

// 删除节点
async function deleteNode(nodeId: number) {const data = await readData();const index = data.nodes.findIndex(node => node.id === nodeId);if (index !== -1) {data.nodes.splice(index, 1);await writeData(data);console.log('Node deleted successfully!');} else {console.log('Node not found!');}
}// 示例:删除 id 为 2 的节点
deleteNode(2);

3.3 更新节点(Update)

更新节点时,我们根据 id 查找并修改节点的属性。

// 更新节点
async function updateNode(updatedNode: GameNode) {const data = await readData();const index = data.nodes.findIndex(node => node.id === updatedNode.id);if (index !== -1) {data.nodes[index] = updatedNode;await writeData(data);console.log('Node updated successfully!');} else {console.log('Node not found!');}
}// 示例:更新 id 为 1 的节点
const updatedNode: GameNode = {id: 1,name: "Updated Hero",description: "The updated description of the hero.",status: "injured"
};updateNode(updatedNode);

3.4 查询节点(Read)

查询节点时,可以根据 id 来获取某个节点,或者根据其他条件筛选。

// 查询节点
async function getNodeById(nodeId: number): Promise<GameNode | undefined> {const data = await readData();return data.nodes.find(node => node.id === nodeId);
}// 示例:查询 id 为 1 的节点
getNodeById(1).then(node => {if (node) {console.log('Found node:', node);} else {console.log('Node not found!');}
});

3.5 查询所有节点

你还可以查询所有节点或过滤特定的节点。

// 获取所有节点
async function getAllNodes(): Promise<GameNode[]> {const data = await readData();return data.nodes;
}// 示例:获取所有节点
getAllNodes().then(nodes => {console.log('All nodes:', nodes);
});

4. 综合代码示例

综合起来,你可以创建一个简单的模块来处理这些操作:

import * as fs from 'fs-extra';interface GameNode {id: number;name: string;description: string;status?: string;additionalInfo?: any;
}interface GameData {nodes: GameNode[];
}// 读取和写入数据
async function readData(): Promise<GameData> {return fs.readJson('gameData.json');
}async function writeData(data: GameData): Promise<void> {await fs.writeJson('gameData.json', data, { spaces: 2 });
}// 增加、删除、更新和查询节点的函数
async function addNode(newNode: GameNode) {const data = await readData();data.nodes.push(newNode);await writeData(data);console.log('Node added successfully!');
}async function deleteNode(nodeId: number) {const data = await readData();const index = data.nodes.findIndex(node => node.id === nodeId);if (index !== -1) {data.nodes.splice(index, 1);await writeData(data);console.log('Node deleted successfully!');} else {console.log('Node not found!');}
}async function updateNode(updatedNode: GameNode) {const data = await readData();const index = data.nodes.findIndex(node => node.id === updatedNode.id);if (index !== -1) {data.nodes[index] = updatedNode;await writeData(data);console.log('Node updated successfully!');} else {console.log('Node not found!');}
}async function getNodeById(nodeId: number): Promise<GameNode | undefined> {const data = await readData();return data.nodes.find(node => node.id === nodeId);
}async function getAllNodes(): Promise<GameNode[]> {const data = await readData();return data.nodes;
}

总结

通过使用 fsfs-extra 模块,我们可以通过读取、修改、删除和写入 JSON 文件来实现基本的 CRUD 操作。虽然这种方法适用于小型项目,但对于大规模的生产应用,建议使用专业的数据库(如 MySQL、PostgreSQL、MongoDB 等),以便更好地处理并发、索引、查询优化等问题。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基础知识-虚拟化(Virtualization)技术

(250106) 参考资料 KVM 虚拟化技术 | cnblogs | 惨绿少年@clsn.io 虚拟化介绍 | cnblogs | 休耕 云计算与虚拟化技术发展编年史 | cnblogs | 云物互联 nova系列二:kvm介绍 | cnblogs | linhaifeng 虚拟化与容器 | cnblogs | marility 《LPIC-3-Virtualization-and-Containe…

【k8s基础】k8s 基本使用

介绍及教程大全 Kubernetes中文文档 结构模型 k8s 是经典的一对多模型,有一个主要的管理节点master和许多的工作节点slaver。当然,k8s 也可以配置多个管理节点,拥有两个以上的管理节点被称为 高可用。k8s 包括了许多的组件,每个组件都是单运行在一个docker容器中,然后通过…

Scss 入门

Scss 是对 CSS 的扩展,提供了比 CSS 更简洁的语法和更强大的功能。不过,在部署时,我们要先把 Scss 编译成 CSS,才能让浏览器识别。编译 Scss 的方法有很多,这里我们使用 VS Code 的插件 Live Sass Compiler 进行自动编译。 基本准备配置保存目录。在 VS Code 配置文件中添…

Seed Lab实验:RSAPublic-Key Encryption and Signature Lab

Seed Lab实验:RSAPublic-Key Encryption and Signature Lab笔记RSAPublic-Key Encryption and Signature Lab 1.推导RSA私钥 import gmpy2p = 0xF7E75FDC469067FFDC4E847C51F452DF q = 0xE85CED54AF57E53E092113E62F436F4F e = 0x0D88C3n = q * p phi = (p - 1) * (q - 1) d =…

双稳态触发器

双稳态触发器双稳态触发器是一种具有记忆功能的逻辑单元电路,它能储存一位二进制码。 特点有两个稳定状态“0”态和“1”态; 能根据输入信号将触发器置成“0”或“1”态; 输入信号消失后,被置成的“0”或“1”态能保存下来,即具有记忆功能。RS触发器 基本RS触发器 输入低电…

在Lazarus下的Free Pascal编程教程——以数据处置推动程序运行的模块化程序设计方法

0.前言 我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。 了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”和…

foobar2000 v2.24.1 汉化版

foobar2000 v2.24.1 汉化版 -----------------------【软件截图】---------------------- -----------------------【软件介绍】---------------------- foobar2000 是一个 Windows 平台下的高级音频播放器.包含完全支持 unicode 及支持播放增益的高级标签功能. 特色: * 支持的…

ABB机器人IO板DSQC652维修方法归纳

ABB机械手IO板DSQC652维修需要一定的专业知识和技能,以下是详细的维修步骤和注意事项:1. 初步检查断电操作:在维修前,确保机器人系统完全断电,避免触电或损坏设备。外观检查:检查DSQC652板是否有明显的物理损坏,如烧焦痕迹、裂纹或元件脱落。连接检查:检查IO板与控制器…

车载以太网一致性测试套件TAE.AETP

随着汽车电子电气架构的发展,高带宽、高速率的数据通信需求逐步涌现,具有稳定、高效特点的车载以太网技术逐步成为汽车主干网通信主流方案。为了满足复杂的通信需求,越来越多的以太网通信协议被应用到车载领域与之而来的是更多新技术的测试验证需求,经纬恒润自主研发的车载…

直播电商运营工具如何选?看这一篇就够了

近年来,直播电商迅速崛起,成为电商行业的新风口。无论是头部主播还是中小商家,都希望通过直播带货实现销售增长。然而,随着市场竞争的加剧,直播电商的运营难度也在不断增加。商家们面临着选品、数据分析、用户互动、流量获取等多重挑战。如何高效管理直播流程、精准分析数…

使用 NodeLocalDNS 提升集群 DNS 性能和可靠性

本文主要分享如何使用 NodeLocal DNSCache 来提升集群中的 DNS 性能以及可靠性,包括部署、使用配置以及原理分析,最终通过压测表明使用后带来了高达 50% 的性能提升。1.背景 什么是 NodeLocalDNS NodeLocal DNSCache 是一套 DNS 本地缓存解决方案。NodeLocal DNSCache 通过在…