简体   繁体   English

如何将 Modified Preorder Tree Traversal 数据填充到 Java 树对象中?

[英]How to populating Modified Preorder Tree Traversal data into Java tree object?

I have the following table with a MPTT structure :我有一个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');

In CakePHP I can make the following data structure :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
                                (
                                )

                        )

                 )

         )
    )

The problem is how can I populate MPTT data structure in Java , using a Java tree class.问题是如何使用Java树类在Java 中填充MPTT数据结构。 Yes, I know Java can not have dynamic array like in PHP , in Java you have to use class Model .是的,我知道Java不能像PHP那样有动态数组,在Java 中你必须使用Model类。

My Model class looks like this:我的模型类看起来像这样:

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;
    }
}

I find it very confusing and I don't know any way on how to do it.我觉得这很令人困惑,我不知道如何去做。 Data that comes from database is populated to a Java tree object.来自数据库的数据被填充到Java树对象中。 I don't know what to do, I don't know how to populate it completely.我不知道该怎么做,我不知道如何完全填充它。 I am using Vivin's GenericTree Java class我正在使用Vivin 的 GenericTree Java 类

I think i need data querying strategy, is it need a recursive function to retrieve all data from database?我想我需要数据查询策略,是否需要递归函数来检索数据库中的所有数据? I think it takes two steps : 1. Querying the data, 2. Populate all data to tree object.我认为这需要两个步骤:1. 查询数据,2. 将所有数据填充到树对象。

You do not really need a generic tree data structure for this.为此,您实际上并不需要通用树数据结构。 Consider the following example:考虑以下示例:

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

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

(getters/setters ommited for conciseness) (为简洁起见省略了 getter/setter)

The parent field helps you set the parent menu and can be null for the root menu. parent字段可帮助您设置父菜单,对于根菜单可以为 null。

Add the Children menu to the children field.将 Children 菜单添加到children字段。

With this you will be able to capture the needs of your hierarchical menu I hope.有了这个,您将能够满足我希望的分层菜单的需求。

Now to build the query supposing you have a result set rs :现在构建查询,假设您有一个结果集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... */));
}

as for find findMenuById it could be something like:至于 find 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;
}

edit编辑

Here is a custom working implementation I made.这是我制作的自定义工作实现。 I inserted your menu in the database and use result set.我在数据库中插入了您的菜单并使用了结果集。 I should be almost the same with the custom abstraction of yours.我应该和你的自定义抽象几乎一样。

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();

Note 1 : I used an HashMap to store the menus that are not attached to the root yet. Note 1 :我使用HashMap来存储尚未附加到根目录的菜单。

Note 2 : This implementation wont work if there are more than one root menu. Note 2 :如果有多个根菜单,此实现将不起作用。

You probably want to add a private Menu menu;您可能想要添加一个private Menu menu; instance variable so that you can model a tree structure实例变量,以便您可以对树结构进行建模

It might be valuable for you to check this Java JPA implementation of MPTT.检查 MPTT 的这个 Java JPA 实现对您来说可能很有价值。 The demo in the source code could give ideas how to model your entity, as well as populating the tree.源代码中的演示可以提供如何对实体建模以及填充树的想法。

https://github.com/hacker-works/mptt-jpa https://github.com/hacker-works/mptt-jpa

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM