1. 程式人生 > >Java非遞迴實現一二選單

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

非遞迴用這種方法還是不錯的。