Java非递归实现一二菜单

转自:https://blog.csdn.net/weixin_38111957/article/details/80330957

一、引言
怎么实现首页中一二级菜单联动效果?在我们开发过程中经常看到有菜单的出现,一般菜单也是有分类的。一般来说一级菜单下有N个二级菜单,在我们做管理系统的时候菜单是必不可免的。那我们应该怎么去设计数据库表结构呢? 有些同学会说用三张表"父级菜单表"、“子级菜单表”、“中间关系表”,用这样的方式去实现。大家有没有觉得这种发式很麻烦呢?那如果我有N级菜单,那是不是就需要建立N张数据库表,而且也不便于维护。 今天我们采用一张表的方式来实现怎么查询出并且组装好参数。

二、实现
1.数据库表结构

CREATE TABLE `sys_module` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `TITLE` varchar(30) DEFAULT NULL COMMENT '菜单标题',
  `INTRO` varchar(300) DEFAULT NULL COMMENT '菜单显示内容',
  `URL` varchar(300) DEFAULT NULL COMMENT '菜单对应的页面url',
  `LEVEL` tinyint(4) DEFAULT NULL COMMENT '显示顺序',
  `PCODE` varchar(60) DEFAULT NULL COMMENT '父级编码',
  `CODE` varchar(60) DEFAULT NULL COMMENT '子级编码',
  `FLAG` tinyint(4) DEFAULT NULL COMMENT '是否有效',
  `CREATEDATE` datetime DEFAULT NULL COMMENT '创建时间',
  `ICONCODE` bigint(20) DEFAULT NULL COMMENT '菜单对应的图标',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='模块';

2.java实体
SysModule对应的是数据库表结构的视图,SysModuleVo实体增加了存放子菜单的属性,分两个文件的原因是为了避免重新生成SysModule实体会覆盖自己自定义的属性。

package cn.zgjkw.battalion.model;
 
import java.util.Date;
 
public class SysModule  {
    private Integer id;
 
    private String title;
 
    private String intro;
 
    private String url;
 
    private Byte level;
 
    private String pcode;
 
    private String code;
 
    private Byte flag;
 
    private Date createdate;
 
    private Long iconcode;
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getTitle() {
        return title;
    }
 
    public void setTitle(String title) {
        this.title = title;
    }
 
    public String getIntro() {
        return intro;
    }
 
    public void setIntro(String intro) {
        this.intro = intro;
    }
 
    public String getUrl() {
        return url;
    }
 
    public void setUrl(String url) {
        this.url = url;
    }
 
    public Byte getLevel() {
        return level;
    }
 
    public void setLevel(Byte level) {
        this.level = level;
    }
 
    public String getPcode() {
        return pcode;
    }
 
    public void setPcode(String pcode) {
        this.pcode = pcode;
    }
 
    public String getCode() {
        return code;
    }
 
    public void setCode(String code) {
        this.code = code;
    }
 
    public Byte getFlag() {
        return flag;
    }
 
    public void setFlag(Byte flag) {
        this.flag = flag;
    }
 
    public Date getCreatedate() {
        return createdate;
    }
 
    public void setCreatedate(Date createdate) {
        this.createdate = createdate;
    }
 
    public Long getIconcode() {
        return iconcode;
    }
 
    public void setIconcode(Long iconcode) {
        this.iconcode = iconcode;
    }
}

package cn.zgjkw.battalion.model.ex;
 
import cn.zgjkw.battalion.model.SysModule;
 
import java.util.List;
 
public class SysModuleVo extends SysModule {
 
    private List<SysModule> listModule;
 
    public List<SysModule> getListModule() {
        return listModule;
    }
 
    public void setListModule(List<SysModule> listModule) {
        this.listModule = listModule;
    }
}

3.组装参数

/**
     * 管理员获取菜单
     * @return
     */
    public List<SysModuleVo> getAdminListModule(){
        SysModuleExample example = new SysModuleExample(); //这个Example类是采用Mybatis生成实体的一起生成的,不清楚的童鞋可以百度一下
        SysModuleExample.Criteria criteria = example.createCriteria();
        criteria.andFlagEqualTo((byte) 1);
 
        //既然是管理用户,理所当然加载出全部的功能菜单。fiag=1:表示有效菜单
        List<SysModule> list =sysModuleDao.selectByExample(example);
 
        //最后返回的容器集合
        List<SysModuleVo> resultList = new ArrayList<>();
 
        //判断查询出来的菜单是否为空
        if(list != null && list.size() > 0 ) {
 
            //让属于相同的父级菜单进行归类
            Map<String,List<SysModule>> map = new HashMap<>();
 
            /**
             * 第一步:让所有具有相同的父级code的子菜单,进行归类
             */
 
            //遍历所有查询出来的功能菜单
            for (SysModule module : list) {
 
                //根据pcode进行分类,pcode:父级菜单的code,pcode=0:表示该菜单是父级菜单
                if(map.get(module.getPcode()) == null){
 
                    //创建一个存放相同父级菜单的子菜单的集合
                    List<SysModule> chmudule = new ArrayList<>();
 
                    //将当前对象存放到集合当中
                    chmudule.add(module);
 
                    //添加到Map当中,已每个菜单的父级pcode作为key
                    map.put(module.getPcode(),chmudule);
                }else{
                    //否则,如果当前map当中有存放相同父级菜单的数据,则取出之前保存的子菜单,添加新的子菜单,然后添加在添加的map当中
                    List<SysModule> modules = map.get(module.getPcode());
 
                    //在之前的子菜单基础之上,添加新的子菜单
                    modules.add(module);
 
                    //添加到Map当中,已每个菜单的父级pcode作为key
                    map.put(module.getPcode(),modules);
 
                }
            }
 
            /**
             * 第二步:遍历所有的父级菜单,通过父级菜单中的code找到对应的子菜单,并添加到集合当中。
             */
 
            //获取所有的父级菜单
            List<SysModule> moduleList = map.get("0");
 
            //遍历所有的父级菜单,通过父级菜单的中的code,获取所有的子菜单
            for (SysModule module : moduleList){
                SysModuleVo moduleVo = new SysModuleVo();
                moduleVo.setId(module.getId());
                moduleVo.setCode(module.getCode());
                moduleVo.setPcode(module.getPcode());
                moduleVo.setCreatedate(module.getCreatedate());
                moduleVo.setFlag(module.getFlag());
                moduleVo.setTitle(module.getTitle());
                moduleVo.setIntro(module.getIntro());
                moduleVo.setListModule(map.get(module.getCode()));
                resultList.add(moduleVo);
            }
        }
 
        return resultList;
    }

非递归用这种方法还是不错的。

猜你喜欢

转载自blog.csdn.net/qq_31279347/article/details/83865485