java - 如何将修改后的预序树遍历数据填充到 Java 树对象中?

标签 java php tree populate mptt

我有下表和一个 MPTT 结构:

CREATE TABLE IF NOT EXISTS menus (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  parent_id int(10) DEFAULT NULL,
  lft int(10) DEFAULT NULL,
  rght int(10) DEFAULT NULL,
  module_name varchar(255) DEFAULT NULL,
  module_controller_name varchar(128) DEFAULT NULL,
  module_action_name varchar(128) DEFAULT NULL,
  alias varchar(128) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

INSERT INTO menus (`id`, `parent_id`, `lft`, `rght`, `module_name`,    
`module_controller_name`, `module_action_name`, `alias`) VALUES (1, NULL, 1, 14,  
'Root', '', '', 'Root'),
(2, 1, 2, 7, 'Toolbox', '', '', 'Toolbox'),
(3, 2, 5, 6, 'Menu Manajemen', 'menus', 'index', 'MenuManajemenz'),
(4, 2, 3, 4, 'Hak Akses Manajemen', 'access_rights', 'index', 'HakAksesManajemen'),
(5, 1, 8, 13, 'Accounts', '', '', 'Accounts'),
(6, 5, 9, 10, 'Users', 'users', 'index', 'Users'),
(7, 5, 11, 12, 'Groups', 'groups', 'index', 'Groups');

CakePHP 中,我可以创建以下数据结构:

Array
(
    [0] => Array
        (
            [Menu] => Array
                (
                    [id] => 2
                    [parent_id] => 1
                    [lft] => 2
                    [rght] => 7
                    [module_name] => Toolbox
                    [module_controller_name] => 
                    [module_action_name] => 
                    [alias] => Toolbox
                )

            [children] => Array
                (
                    [0] => Array
                        (
                            [Menu] => Array
                                (
                                    [id] => 4
                                    [parent_id] => 2
                                    [lft] => 3
                                    [rght] => 4
                                    [module_name] => Hak Akses Manajemen
                                    [module_controller_name] => access_rights
                                    [module_action_name] => index
                                    [alias] => HakAksesManajemen
                                )

                            [children] => Array
                                (
                                )

                        )

                    [1] => Array
                        (
                            [Menu] => Array
                                (
                                    [id] => 3
                                    [parent_id] => 2
                                    [lft] => 5
                                    [rght] => 6
                                    [module_name] => Menu Manajemen
                                    [module_controller_name] => menus
                                    [module_action_name] => index
                                    [alias] => MenuManajemenz
                                )

                             [children] => Array
                                (
                                )

                        )

                 )

         )
    )

问题是如何使用 Java 树类在 Java 中填充 MPTT 数据结构。是的,我知道 Java 不能像 PHP 那样拥有动态数组,在 Java 中你必须使用类 Model .

我的模型类如下所示:

public class Menu {
    private String moduleName;
    private String moduleControllerName;
    private String moduleActionName;
    private String alias;

    public String getModuleName() {
        return moduleName;
    }

    public void setModuleName(String moduleName) {
        this.moduleName = moduleName;
    }

    public String getModuleControllerName() {
        return moduleControllerName;
    }

    public void setModuleControllerName(String moduleControllerName) {
        this.moduleControllerName = moduleControllerName;
    }

    public String getModuleActionName() {
        return moduleActionName;
    }

    public void setModuleActionName(String moduleActionName) {
        this.moduleActionName = moduleActionName;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }
}

我觉得这很困惑,我不知道该怎么做。来自数据库的数据被填充到一个 Java 树对象中。我不知道该怎么做,我不知道如何完全填充它。我正在使用 Vivin's GenericTree Java class

我想我需要数据查询策略,是否需要一个递归函数来从数据库中检索所有数据?我认为这需要两个步骤:1.查询数据,2.将所有数据填充到树对象。

最佳答案

你并不真的需要一个通用的树数据结构。考虑以下示例:

private static final class Menu {
    private Menu parent;
    private List<Menu> children;

    private String moduleName;
    private String moduleControllerName;
    private String moduleActionName;
    private String alias;
}

(为简洁起见省略了 getter/setter)

parent 字段帮助您设置父菜单,对于根菜单可以为 null。

将 Children 菜单添加到 children 字段。

我希望有了它,您将能够捕获分层菜单的需求。

现在构建查询,假设您有一个结果集 rs:

Menu menu;

while (rs.hasNext()) {
    if (rs.get("parent_id") == null) {
        // it s the root
        menu = new Menu(rs.get("id"), /* etc... */);
    } else {
        menu = findMenuById(menu, rs.get("parent_id"));
        menu.addChild(new Menu(rs.get("id"), /* etc... */));
}

对于查找 findMenuById 它可能是这样的:

private Menu findMenuById(Menu menu, Long id) {
    if (menu.getId() == id) return menu;
    for (Menu childMenu : menu.getChildren()) {
        Menu found = findMenuById(childMenu, id);
        if (found != null) return found;
    }
    return null;
}

编辑

这是我制作的自定义工作实现。我将您的菜单插入数据库并使用结果集。我应该与您的自定义抽象几乎相同。

Menu root = null;
        Map<Integer, Menu> menus = new HashMap<Integer, Menu>();

        final Database databaseConnection = Database.createConnection("test", "root", "");
        final ResultSet rs = databaseConnection.executeQuery("SELECT * FROM test.menus;");
        while ( rs.next() ) {
            final Menu menu = new Menu(rs.getInt("id"))
                .setAlias(rs.getString("alias"))
                .setModuleName(rs.getString("module_name"));

            final Integer parentId = rs.getInt("parent_id");
            if (root == null && parentId == 0) {
                root = menu;
            } else {
                menus.get(parentId).addSubMenu(menu);
            }

            menus.put(menu.getId(), menu);
        }

        rootMenu = root;

        databaseConnection.closeConnection();

注意 1:我使用了一个 HashMap 来存储尚未附加到根的菜单。

注释 2:如果有多个根菜单,则此实现将不起作用。

关于java - 如何将修改后的预序树遍历数据填充到 Java 树对象中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12910719/

相关文章:

java - setImageResource 崩溃程序

java - JAX-RS 和 JSON 搞砸了

php - 如何在 PHP 中使用子目录中的配置文件并将其保存在根目录中

php - WooCommerce选择性地显示缺货的产品

algorithm - 从其前序和后序列表中重建一棵树

d3.js - 如何使用非树数据创建 d3.js 可折叠力布局?

java - 在 Java 中从特定 IP 生成 HttpRequest

java - locationManager.getLastKnownLocation 请求后返回 null

php - "Strict Standards: Only variables should be passed by reference"错误

c# - 从列表列表创建树 C#