4

我有一个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 的 GenericTree Java 类

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

4

3 回答 3

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字段可帮助您设置父菜单,并且可以为根菜单为空。

将“儿童”菜单添加到该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... */));
}

至于 findfindMenuById它可能是这样的:

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

Note 1: 我用 anHashMap来存储尚未附加到根目录的菜单。

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

于 2012-10-16T09:00:18.090 回答
1

您可能想要添加一个private Menu menu;实例变量,以便您可以对树结构进行建模

于 2012-10-16T08:59:36.287 回答
0

检查 MPTT 的 Java JPA 实现可能对您很有价值。源代码中的演示可以提供如何建模实体以及填充树的想法。

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

于 2020-07-01T13:21:13.507 回答