将多层树状结构扁平化并存入MySQL

在实际开发中,常常遇到需要将多层树状结构的数据扁平化,便于存储到关系型数据库如MySQL中的情况。本文将为您详细介绍如何在Java中实现这个需求,并提供相应的代码示例。

概述

树状结构常用于表示层级关系的复杂数据。例如,文件系统、组织结构图等。为了将这些数据存入数据库,我们需要将树状结构转换为扁平化的表格结构。

关系图

首先,我们可以利用Mermaid语法表示树状结构与数据库表之间的关系图。

erDiagram
    TreeNode {
        int id PK "节点ID"
        int parentId "父节点ID"
        string name "节点名称"
    }

    MySQLTable {
        int id PK "节点ID"
        int parentId "父节点ID"
        string name "节点名称"
        int level "层级"
    }

    TreeNode ||--o{ MySQLTable : transforms_to

在上面的ER图中,我们看到一个TreeNode表示我们的树状结构,而MySQLTable是用来存储扁平化数据的表。

多层树状结构的定义

首先,我们定义一个类来表示树状结构中的每一个节点。

树节点类

public class TreeNode {
    private int id;
    private int parentId;
    private String name;
    private List<TreeNode> children;

    // 构造方法
    public TreeNode(int id, int parentId, String name) {
        this.id = id;
        this.parentId = parentId;
        this.name = name;
        this.children = new ArrayList<>();
    }

    // Getter和Setter
    public int getId() { return id; }
    public int getParentId() { return parentId; }
    public String getName() { return name; }
    public List<TreeNode> getChildren() { return children; }
    
    public void addChild(TreeNode child) {
        children.add(child);
    }
}

在这个类中,每个节点都有一个ID、父节点ID、名称和子节点列表。

扁平化树结构

接下来,我们需要编写代码,将树状结构扁平化为简单的列表,方便后续插入数据库。

扁平化方法

import java.util.ArrayList;
import java.util.List;

public class TreeFlattener {
    private final List<MySQLTable> flatList = new ArrayList<>(); // 扁平化结果列表

    public void flatten(TreeNode node, int level) {
        // 将当前节点添加到扁平列表
        MySQLTable tableEntry = new MySQLTable(node.getId(), node.getParentId(), node.getName(), level);
        flatList.add(tableEntry);

        // 递归遍历子节点
        for (TreeNode child : node.getChildren()) {
            flatten(child, level + 1); // 层级加1
        }
    }

    public List<MySQLTable> getFlatList() {
        return flatList;
    }
}

在这个类中,flatten方法接受一个TreeNode和其所在的层级,通过递归方式将树状结构转化为扁平结构。

扁平化表结构类

为了将数据插入MySQL,我们需要定义与MySQL表结构相对应的Java类。

public class MySQLTable {
    private int id;
    private int parentId;
    private String name;
    private int level;

    // 构造方法
    public MySQLTable(int id, int parentId, String name, int level) {
        this.id = id;
        this.parentId = parentId;
        this.name = name;
        this.level = level;
    }

    // Getter和Setter
    public int getId() { return id; }
    public int getParentId() { return parentId; }
    public String getName() { return name; }
    public int getLevel() { return level; }
}

数据库操作

现在,我们可以编写功能将扁平化后的数据插入到MySQL数据库中。假设我们已经创建了名为Tree的表,其列与MySQLTable类的属性匹配。

数据库插入方法

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

public class MySQLDatabase {
    private static final String URL = "jdbc:mysql://localhost:3306/your_database";
    private static final String USER = "your_username";
    private static final String PASSWORD = "your_password";

    public void insertData(List<MySQLTable> flatList) {
        String sql = "INSERT INTO Tree (id, parentId, name, level) VALUES (?, ?, ?, ?)";

        try (Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            for (MySQLTable entry : flatList) {
                pstmt.setInt(1, entry.getId());
                pstmt.setInt(2, entry.getParentId());
                pstmt.setString(3, entry.getName());
                pstmt.setInt(4, entry.getLevel());
                pstmt.addBatch(); // 批量执行
            }

            pstmt.executeBatch(); // 执行批处理插入
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

主方法示例

最终,在主方法中,通过组合上述类,完成扁平化和数据库插入的整个过程。

public class Main {
    public static void main(String[] args) {
        // 创建根节点和子节点构造树的结构
        TreeNode root = new TreeNode(1, 0, "Root");
        TreeNode child1 = new TreeNode(2, 1, "Child 1");
        TreeNode child2 = new TreeNode(3, 1, "Child 2");
        TreeNode grandChild = new TreeNode(4, 2, "Grandchild");

        root.addChild(child1);
        root.addChild(child2);
        child1.addChild(grandChild);

        // 扁平化树形结构
        TreeFlattener flattener = new TreeFlattener();
        flattener.flatten(root, 0);
        List<MySQLTable> flatList = flattener.getFlatList();

        // 将数据插入MySQL
        MySQLDatabase database = new MySQLDatabase();
        database.insertData(flatList);
    }
}

结论

通过以上步骤,我们成功地将多层树状结构扁平化,并存入MySQL数据库。这一过程的关键在于采用递归方法来解析树结构,并利用批量插入来提高数据库操作的效率。

未来,可以进一步优化插入操作,例如使用事务处理,或者选用更高效的ORM(对象关系映射)框架。希望本文能对你在实际开发中遇到类似问题有所帮助!