Node.js中如何建立JSON表:从基础到实践
在Node.js开发中,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,因其易读性和与JavaScript的天然兼容性,被广泛应用于数据存储、配置文件、API响应等场景,所谓“JSON表”,通常指通过JSON结构来组织和管理表格类数据(如二维表、结构化记录),实现数据的增删改查(CRUD)操作,本文将详细介绍在Node.js中建立JSON表的完整流程,从数据结构设计到具体操作实现,帮助开发者快速上手。
明确JSON表的数据结构设计
在开始建立JSON表之前,首先需要明确“表”的数据结构,JSON表的本质是通过嵌套的JSON对象或数组来模拟传统数据库表的结构,核心是确定“行”和“列”的表示方式,常见的两种设计模式如下:
数组存储模式(行优先)
将每一行数据作为一个JSON对象,所有行对象存储在一个大数组中,对象的键(key)对应表的列名,值(value)对应单元格数据,这是最直观、最常用的JSON表设计方式,例如存储用户信息表:
[
{
"id": 1,
"name": "张三",
"age": 25,
"email": "zhangsan@example.com",
"createAt": "2023-01-01"
},
{
"id": 2,
"name": "李四",
"age": 30,
"email": "lisi@example.com",
"createAt": "2023-01-02"
}
]
优点:结构清晰,遍历行数据方便,适合直接序列化为JSON文件或API响应。
缺点:列不固定时(如动态字段),需统一处理键名;查询效率依赖数组遍历。
对象存储模式(列优先或键值对)
以对象为容器,通过“主键-行数据”的方式存储,主键通常是表的唯一标识(如id)。
{
"1": {
"id": 1,
"name": "张三",
"age": 25,
"email": "zhangsan@example.com",
"createAt": "2023-01-01"
},
"2": {
"id": 2,
"name": "李四",
"age": 30,
"email": "lisi@example.com",
"createAt": "2023-01-02"
}
}
优点:通过主键直接定位行数据,查询效率高(无需遍历数组)。
缺点:主键需唯一,且无法直接获取所有行(需先获取对象键)。
选择建议:如果数据量小、需频繁遍历行(如前端渲染),优先选择数组模式;如果需通过主键快速查询(如后端API查询),优先选择对象模式,本文以更通用的数组模式为例展开讲解。
创建JSON表文件
设计好数据结构后,首先需要创建一个JSON文件来存储表数据,假设我们要创建一个users.json文件,存储用户信息表:
手动创建初始文件
在项目根目录下创建data文件夹(用于隔离数据文件),并在其中创建users.json为空数组:
[]
通过Node.js动态创建文件(可选)
如果希望代码中自动初始化文件(如首次运行时),可以使用Node.js的fs(文件系统)模块:
const fs = require('fs');
const path = require('path');
// 确保data目录存在
const dataDir = path.join(__dirname, 'data');
if (!fs.existsSync(dataDir)) {
fs.mkdirSync(dataDir);
}
// 创建初始JSON表文件
const jsonFilePath = path.join(dataDir, 'users.json');
const initialData = []; // 初始空数组
// 写入文件(需将数组转为JSON字符串)
fs.writeFileSync(jsonFilePath, JSON.stringify(initialData, null, 2), 'utf8');
console.log('JSON表文件创建成功:', jsonFilePath);
运行后,会自动生成data/users.json为[]。
实现JSON表的CRUD操作
JSON表的核心是数据的增删改查,Node.js中通过fs模块读写文件,结合JSON序列化/反序列化操作即可实现。
读取JSON表数据
读取数据时,需将JSON文件内容解析为JavaScript对象(数组或对象),封装一个readJsonTable函数:
const fs = require('fs');
const path = require('path');
/**
* 读取JSON表数据
* @param {string} fileName - JSON文件名(如users.json)
* @returns {Array|Object} - 返回解析后的数据(数组或对象)
*/
function readJsonTable(fileName) {
const jsonFilePath = path.join(__dirname, 'data', fileName);
try {
const data = fs.readFileSync(jsonFilePath, 'utf8');
return JSON.parse(data); // 解析JSON字符串为JS对象
} catch (error) {
console.error('读取JSON表失败:', error.message);
return fileName.endsWith('.json') ? [] : {}; // 默认返回空数组或对象
}
}
// 示例:读取users.json
const usersTable = readJsonTable('users.json');
console.log('当前用户表:', usersTable);
插入数据(新增行)
向JSON表中插入一行数据,需先读取现有数据,追加新数据,再写回文件,假设新增用户数据:
/**
* 向JSON表中插入一行数据
* @param {string} fileName - JSON文件名
* @param {Object} newData - 新行数据(需包含唯一标识,如id)
*/
function insertData(fileName, newData) {
const tableData = readJsonTable(fileName);
// 检查唯一性(示例:检查id是否重复)
if (tableData.some(item => item.id === newData.id)) {
throw new Error(`数据id ${newData.id} 已存在,插入失败`);
}
tableData.push(newData); // 追加到数组末尾
// 写回文件
const jsonFilePath = path.join(__dirname, 'data', fileName);
fs.writeFileSync(jsonFilePath, JSON.stringify(tableData, null, 2), 'utf8');
console.log(`数据插入成功:`, newData);
}
// 示例:插入新用户
const newUser = {
id: 3,
name: '王五',
age: 28,
email: 'wangwu@example.com',
createAt: new Date().toISOString().split('T')[0] // 2023-10-01
};
insertData('users.json', newUser);
查询数据(按条件筛选)
查询数据本质是遍历JSON数组(或对象),匹配条件后返回结果,支持按单条件或多条件查询:
/**
* 查询JSON表数据(支持单条件或多条件)
* @param {string} fileName - JSON文件名
* @param {Object} conditions - 查询条件(如{age: 25}或{name: '张三', age: 25})
* @returns {Array} - 匹配的数据数组
*/
function queryData(fileName, conditions) {
const tableData = readJsonTable(fileName);
return tableData.filter(item => {
return Object.keys(conditions).every(key => item[key] === conditions[key]);
});
}
// 示例1:查询年龄为25的用户
const usersByAge = queryData('users.json', { age: 25 });
console.log('年龄为25的用户:', usersByAge);
// 示例2:查询名字为'张三'且年龄为25的用户
const userByNameAndAge = queryData('users.json', { name: '张三', age: 25 });
console.log('名字为张三且年龄25的用户:', userByNameAndAge);
更新数据(修改行)
更新数据需先根据条件找到目标行,修改其字段,再写回文件,通常通过唯一标识(如id)定位:
/**
* 更新JSON表数据(根据id修改)
* @param {string} fileName - JSON文件名
* @param {number|string} id - 目标行的唯一标识
* @param {Object} updateData - 需更新的字段(如{name: '新名字'})
*/
function updateData(fileName, id, updateData) {
const tableData = readJsonTable(fileName);
const itemIndex = tableData.findIndex(item => item.id === id);
if (itemIndex === -1) {
throw new Error(`未找到id为 ${id} 的数据,更新失败`);
}
// 合并更新数据(保留原有字段,覆盖新字段)
tableData[itemIndex] = { ...tableData[itemIndex], ...updateData };
// 写回文件
const jsonFilePath = path.join


还没有评论,来说两句吧...