如何用JavaScript构建从MySQL查询的三表数据双重嵌套JSON对象
如何用JavaScript构建双重嵌套JSON对象(从MySQL查询结果)
嘿,我懂你现在的状况——已经把MySQL里三张表的数据都查出来了,确认SQL语句完全没问题,就差用JavaScript把这些零散的数据拼成想要的双重嵌套JSON结构对吧?别慌,咱们一步步来搞定这个事儿!
先明确场景(举个例子)
因为不清楚你三张表的具体结构,我先拿一个非常常见的电商场景举例:
- 父表:
categories(分类,字段:categoryId,categoryName) - 中间表:
products(产品,字段:productId,productName,categoryId) - 子表:
variants(产品规格,字段:variantId,color,price,productId)
我们要构建的目标双重嵌套JSON结构是:
[ { "categoryId": 1, "categoryName": "电子产品", "products": [ { "productId": 101, "productName": "智能手机", "variants": [ {"variantId": 1001, "color": "黑色", "price": 4999}, {"variantId": 1002, "color": "白色", "price": 4999} ] } ] } ]
具体实现步骤(假设你已拿到三组数据)
假设你已经通过MySQL驱动(比如mysql2、sequelize)拿到了三个数组:categoriesData(分类数据)、productsData(产品数据)、variantsData(规格数据)。
1. 先给最底层数据建立映射,方便快速查找
首先把最底层的规格数据,按所属的产品ID分组,这样后面找对应产品的规格时不用循环遍历,效率更高:
// 把规格数据按productId分组,生成一个映射对象 const variantsByProduct = variantsData.reduce((acc, variant) => { const { productId } = variant; // 如果当前productId还没在映射里,先初始化一个空数组 if (!acc[productId]) { acc[productId] = []; } acc[productId].push(variant); return acc; }, {});
2. 处理中间层数据,嵌套最底层数据
接下来处理产品数据,把对应的规格数组嵌套进去,然后再按所属的分类ID分组:
// 处理产品数据,嵌套规格后按categoryId分组 const productsByCategory = productsData.reduce((acc, product) => { const { categoryId, productId } = product; // 给当前产品添加对应的规格数组,没有的话就用空数组兜底 const productWithVariants = { ...product, variants: variantsByProduct[productId] || [] }; // 如果当前categoryId还没在映射里,初始化空数组 if (!acc[categoryId]) { acc[categoryId] = []; } acc[categoryId].push(productWithVariants); return acc; }, {});
3. 处理最顶层数据,完成双重嵌套
最后把分类数据和对应的产品数组结合,得到最终的双重嵌套结构:
// 构建最终的双重嵌套JSON对象 const nestedJson = categoriesData.map(category => { return { ...category, // 给分类添加对应的产品数组,没有的话用空数组兜底 products: productsByCategory[category.categoryId] || [] }; }); // 如果需要转成JSON字符串输出,就用下面这句 const nestedJsonString = JSON.stringify(nestedJson, null, 2);
关键注意事项
- 适配你的表结构:如果你的表字段、关联键和例子不一样,只需要把代码里的
categoryId、productId换成你自己的主键/外键字段名就行。 - 数据关联校验:确保查询出来的数据里,外键和主键是一一对应的,避免出现找不到对应子数据的情况。
- ORM替代方案:如果你用的是Sequelize这类ORM,其实可以直接用
include做关联查询自动生成嵌套结构,但既然你已经自己完成了SQL查询,上面的方法就非常适用。
内容的提问来源于stack exchange,提问作者Siddiqui
相关产品推荐
相关产品推荐

