我有下表带有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:如果有多个根菜单,则此实现不起作用.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。