如何用JavaScript将树形组织JSON批量插入含层级关联的数据库?
多父多子关联组织结构数据批量插入数据库的JavaScript实现
问题背景
给定如下树形结构的组织JSON数据,需要开发API一次性将所有数据插入数据库,且组织存在多父多子关联关系:
{ "org_name": "organisation", "childrens": [ { "org_name": "company tree", "childrens": [ { "org_name": "company one" }, { "org_name": "company two" }, { "org_name": "company three" } ] }, { "org_name": "Big organisation", "childrens": [ { "org_name": "company one" }, { "org_name": "company two" }, { "org_name": "company four" }, { "org_name": "company three", "childrens": [ { "org_name": "smal farm" } ] } ] } ] }
数据库表结构定义如下:
id | org_name | level | parent -- *level:标识节点在树形结构中的层级,用于维护关联关系
实现思路
由于组织存在多父多子关联,同一组织可能属于多个父节点,因此数据库表中同一org_name可对应多条记录,每条记录对应一个父节点关联。核心实现逻辑:
- 采用深度优先递归遍历树形结构,先插入父节点并获取其ID,再插入子节点时关联该父ID
- 维护节点的层级信息,根节点层级为0,子节点层级依次+1
- 使用数据库事务保证所有插入操作的原子性,避免部分插入失败导致数据混乱
JavaScript实现示例(基于Node.js + MySQL)
1. 安装依赖
npm install mysql2
2. 代码实现
const mysql = require('mysql2/promise'); // 数据库连接配置,替换为你的实际配置 const dbConfig = { host: 'localhost', user: 'your_db_user', password: 'your_db_password', database: 'your_db_name' }; // 递归插入单个节点及其子节点 async function insertOrgNode(node, parentId = null, level = 0, connection) { // 插入当前节点:org_name、层级、父节点ID const [insertResult] = await connection.query( 'INSERT INTO organisations (org_name, level, parent) VALUES (?, ?, ?)', [node.org_name, level, parentId] ); const currentNodeId = insertResult.insertId; // 递归处理子节点,层级+1,父ID为当前节点ID if (node.childrens && node.childrens.length > 0) { for (const child of node.childrens) { await insertOrgNode(child, currentNodeId, level + 1, connection); } } } // 批量插入整个组织结构 async function batchInsertOrgData(orgTree) { let connection; try { // 创建数据库连接 connection = await mysql.createConnection(dbConfig); // 开启事务,保证所有操作原子性 await connection.beginTransaction(); // 从根节点开始插入 await insertOrgNode(orgTree, null, 0, connection); // 提交事务 await connection.commit(); console.log('组织结构数据全部插入成功'); } catch (error) { // 出错则回滚事务 if (connection) await connection.rollback(); console.error('数据插入失败,已回滚:', error.message); throw error; } finally { // 关闭数据库连接 if (connection) await connection.end(); } } // 调用示例 const orgTree = { "org_name": "organisation", "childrens": [ { "org_name": "company tree", "childrens": [ { "org_name": "company one" }, { "org_name": "company two" }, { "org_name": "company three" } ] }, { "org_name": "Big organisation", "childrens": [ { "org_name": "company one" }, { "org_name": "company two" }, { "org_name": "company four" }, { "org_name": "company three", "childrens": [ { "org_name": "smal farm" } ] } ] } ] }; batchInsertOrgData(orgTree);
关键说明
- 多父关联支持:同一组织(如
company one)在不同父节点下会被插入多条记录,每条记录的parent字段对应不同的父节点ID,满足多父关联需求 - 事务保障:所有插入操作在一个事务中执行,若某一步出错则全部回滚,避免数据不一致
- 层级维护:递归时自动维护节点层级,根节点为0,子节点层级递增
扩展优化
- 若需避免同一组织在同一父节点下重复插入,可给表添加
(org_name, parent)联合唯一约束,或插入前先查询判断 - 针对超大树形结构,可将递归改为迭代遍历,避免栈溢出
- 添加日志记录,跟踪每个节点的插入状态,方便问题排查
内容的提问来源于stack exchange,提问作者code_freak
相关产品推荐
相关产品推荐

