当前位置:   article > 正文

Java代码实现项目两级菜单展示(图文教程)_java 创建二级菜单 数据库设计

java 创建二级菜单 数据库设计

本微博只适用于两层的菜单展示,写作的初衷是为了介绍递归做铺垫。

详细说明都写在了代码的注释上,不做单独说明了,希望对你有所帮助。

1.数据库设计

为了方便大家练习,提供建表SQL如下:

  1. -- ----------------------------
  2. -- Table structure for sys_menu
  3. -- ----------------------------
  4. DROP TABLE IF EXISTS `sys_menu`;
  5. CREATE TABLE `sys_menu` (
  6. `menu_id` bigint(20) NOT NULL AUTO_INCREMENT,
  7. `parent_id` bigint(20) DEFAULT NULL COMMENT '父菜单ID,一级菜单为0',
  8. `name` varchar(50) DEFAULT NULL COMMENT '菜单名称',
  9. `url` varchar(200) DEFAULT NULL COMMENT '菜单URL',
  10. `perms` varchar(500) DEFAULT NULL COMMENT '授权(多个用逗号分隔,如:user:list,user:create)',
  11. `type` int(11) DEFAULT NULL COMMENT '类型 0:目录 1:菜单 2:按钮',
  12. `icon` varchar(50) DEFAULT NULL COMMENT '菜单图标',
  13. `order_num` int(11) DEFAULT NULL COMMENT '排序',
  14. `gmt_create` datetime DEFAULT NULL COMMENT '创建时间',
  15. `gmt_modified` datetime DEFAULT NULL COMMENT '修改时间',
  16. PRIMARY KEY (`menu_id`)
  17. ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COMMENT='菜单管理';

2.实体类MenuDO

该实体类是在工作中总结出来的,字段较全,适用场景也比较多。但实际上,最主要的字段只有前几个:menuId、parentId、name、url。

  1. import java.io.Serializable;
  2. import java.util.Date;
  3. public class MenuDO implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. // 主键
  6. private Long menuId;
  7. // 父菜单ID,一级菜单为0
  8. private Long parentId;
  9. // 菜单名称
  10. private String name;
  11. // 菜单URL
  12. private String url;
  13. // 授权(多个用逗号分隔,如:user:list,user:create)
  14. private String perms;
  15. // 类型 0:目录 1:菜单 2:按钮
  16. private Integer type;
  17. // 菜单图标
  18. private String icon;
  19. // 排序
  20. private Integer orderNum;
  21. // 创建时间
  22. private Date gmtCreate;
  23. // 修改时间
  24. private Date gmtModified;
  25. ......
  26. // 省略get()、set()等方法
  27. }

3.业务类Tree<T>

  1. public class Tree<T> {
  2. // 节点ID
  3. private String id;
  4. // 显示节点文本
  5. private String text;
  6. // 节点状态,open closed
  7. private Map<String, Object> state;
  8. // 节点是否被选中 true false
  9. private boolean checked = false;
  10. // 节点属性
  11. private Map<String, Object> attributes;
  12. // 节点的子节点
  13. private List<Tree<T>> children = new ArrayList<Tree<T>>();
  14. // 父ID
  15. private String parentId;
  16. // 是否有父节点
  17. private boolean hasParent = false;
  18. // 是否有子节点
  19. private boolean hasChildren = false;
  20. ......
  21. // 省略get()、set()等方法
  22. }

4.service层调用的方法

返回的list结果,就是满足逻辑的tree型数据,可以直接返回给页面使用。

  1. public List<Tree<MenuDO>> listMenuTree() {
  2. String idParam = "0"; // 自定义顶级结点
  3. List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>(); // 存放结果
  4. List<MenuDO> menuDOs = menuMapper.queryList(); // 取出数据
  5. // 1. 初步处理:让原始数据具备我们自定的的tree的特征
  6. for (MenuDO sysMenuDO : menuDOs) {
  7. Tree<MenuDO> tree = new Tree<MenuDO>();
  8. tree.setId(sysMenuDO.getMenuId().toString());
  9. tree.setParentId(sysMenuDO.getParentId().toString());
  10. tree.setText(sysMenuDO.getName());
  11. Map<String, Object> attributes = new HashMap<>(16);
  12. attributes.put("url", sysMenuDO.getUrl());
  13. attributes.put("icon", sysMenuDO.getIcon());
  14. tree.setAttributes(attributes);
  15. trees.add(tree);
  16. }
  17. // 2. 递归处理:根据数据库实际情况调整顶级结点的parentId值,默认为0
  18. List<Tree<MenuDO>> list = BuildTree.buildList(trees, idParam);
  19. return list;
  20. }

5.util类

  1. import java.util.ArrayList;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;
  5. /**
  6. * 递归树形结构类
  7. */
  8. public class BuildTree {
  9. /**
  10. * 自定义顶级结点的parentId,返回递归树形结构
  11. */
  12. public static <T> List<Tree<T>> buildList(List<Tree<T>> nodes, String idParam) {
  13. // 1.非空判断
  14. if (nodes == null) {
  15. return null;
  16. }
  17. // 2.定义返回数据类型
  18. List<Tree<T>> topNodes = new ArrayList<Tree<T>>();
  19. // 3.取出每一个元素,判断它有没有父类
  20. for (Tree<T> children : nodes) {
  21. String pid = children.getParentId();
  22. // 3.1 pid(parentId)为空,或者等于父节点,则没有父类,直接返回
  23. if (pid == null || idParam.equals(pid)) {
  24. topNodes.add(children);
  25. continue;
  26. }
  27. // 3.2 否则,遍历一遍集合,找它的父类,原则:子类的parentId = 父类的id
  28. for (Tree<T> parent : nodes) {
  29. String id = parent.getId();
  30. if (id != null && id.equals(pid)) {
  31. // 3.2.1 将子类添加到父类的children属性下
  32. parent.getChildren().add(children);
  33. // 3.2.2 设置子节点闭合状态:true - 关闭
  34. children.setHasParent(true);
  35. parent.setChildren(true);
  36. }
  37. }
  38. }
  39. // 4. 返回结果集
  40. return topNodes;
  41. }
  42. }

6.结果展示

基于BootDo成熟的架构,小编自己搭建了一个开发框架,使用递归展示菜单栏,效果如下:

 

更多精彩,请关注我的"今日头条号":Java云笔记
随时随地,让你拥有最新,最便捷的掌上云服务

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/686040
推荐阅读
相关标签
  

闽ICP备14008679号