编程语言
首页 > 编程语言> > 如何将Modified Preorder Tree Traversal数据填充到Java树对象中?

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

作者:互联网

我有下表带有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.

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

(getters / setters因简洁而无视)

父字段可帮助您设置父菜单,对于根菜单可以为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... */));
}

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

编辑

这是我制作的自定义工作实现.我在数据库中插入了菜单并使用结果集.对于你的自定义抽象,我应该差不多了.

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:如果有多个根菜单,则此实现不起作用.

标签:php,java,tree,populate,mptt
来源: https://codeday.me/bug/20190629/1331184.html