首页 > 代码库 > 递归解决根据父节点遍历权限树菜单的问题--------mysql数据中的树表

递归解决根据父节点遍历权限树菜单的问题--------mysql数据中的树表

本人几乎没写过博客,感觉要学的知识和要做的事情太多,没时间。但发现用博客记录自己学习心得非常好,就抽时间写点,供自己以后参考也分享给某些需要的人,我水平有限,请多指教!

最近在独自尝试开发一个小型的oa系统以巩固下自己对java ssh框架的学习。这里记录下开发中的一些心得体会。

我把系统菜单设计成树,用一张表存储,各个菜单项之间是父子关系,当我们要根据用户权限去数据库中取菜单项时,发现sql语句不好解决。之前在网上查看了一些帖子博文,发现oracle中有对这个需求有专门的sql语句:类似这样

select * from pub_entity a start with a.entity_id = 88 connect by prior a.entity_id = a.super_entity_id;

但我使用的mysql没有,一些文章中说用mysql的存储过程解决,我这个刚出道的菜鸟感觉太复杂了,没去尝试。最后想到可以直接用递归算法解决:

菜单表:

技术分享

实体类代码:

  1 package com.xuwei.oa.entity;  2   3 import java.io.Serializable;  4 import java.util.Set;  5   6 import javax.persistence.Column;  7 import javax.persistence.Entity;  8 import javax.persistence.GeneratedValue;  9 import javax.persistence.GenerationType; 10 import javax.persistence.Id; 11 import javax.persistence.ManyToMany; 12 import javax.persistence.Table; 13  14 import org.apache.struts2.json.annotations.JSON; 15 import org.hibernate.annotations.GenericGenerator; 16  17 /** 18  * 菜单管理实体类 19  * @author David 20  * 21  */ 22 @Entity 23 @Table(name="t_menu") 24 public class Menu implements Serializable{ 25     @Id  //设置主键生成策略为手动分配 26     @GenericGenerator(name="menuGenerator",strategy="assigned") 27     @GeneratedValue(generator="menuGenerator") 28     private Long mid;//主键 29     @Column(name = "name", length = 15) 30     private String name;//树上的节点的名称 31     @Column(name = "isParent") 32     private Boolean isParent;//是否为文件夹节点 33     @Column(name = "icon", length = 100) 34     private String icon;//图标图片的路径 35     @Column(name = "checked", length = 5) 36     private Boolean checked; 37     @Column(name = "url", length = 60) 38     private String url;//单击菜单跳转的action 39     @Column(name = "target", length = 15) 40     private String target;//页面显示位置 41     @Column(name = "pid", length = 5) 42     private Long pid;//父节点ID 43      44     public Long getMid() { 45         return mid; 46     } 47     public void setMid(Long mid) { 48         this.mid = mid; 49     } 50     public Long getPid() { 51         return pid; 52     } 53     public void setPid(Long pid) { 54         this.pid = pid; 55     } 56     public String getName() { 57         return name; 58     } 59     public void setName(String name) { 60         this.name = name; 61     } 62     public Boolean getIsParent() { 63         return isParent; 64     } 65     public void setIsParent(Boolean isParent) { 66         this.isParent = isParent; 67     } 68     public String getIcon() { 69         return icon; 70     } 71     public void setIcon(String icon) { 72         this.icon = icon; 73     } 74     public Boolean getChecked() { 75         return checked; 76     } 77     public void setChecked(Boolean checked) { 78         this.checked = checked; 79     } 80     public String getUrl() { 81         return url; 82     } 83     public void setUrl(String url) { 84         this.url = url; 85     } 86     public String getTarget() { 87         return target; 88     } 89     public void setTarget(String target) { 90         this.target = target; 91     } 92      93     @ManyToMany(mappedBy = "menus")   94     private Set<User> users;//角色set集合 95     @JSON(serialize=false) 96     public Set<User> getUsers() { 97         return users; 98     } 99     public void setUsers(Set<User> users) {100         this.users = users;101     }102     103 104 }

单元测试代码:

 1     private Session session; 2     private List<Menu> listMenu=new ArrayList<Menu>(); 3  4  5     @Test 6     public void testQueryAllTreeNodesByRootPid(){ 7         List<Menu> res=new ArrayList<Menu>(); 8         session.beginTransaction(); 9 //        vistTreeNodesByPid(6L);10         vistTreeNodesByPid(6L,res);11         for(Menu m:res){12             System.out.println("*****"+m.getName());13         }14         session.getTransaction().commit();15     }16     17     public void vistTreeNodesByPid(Long pid,List<Menu> res){18 //        String hql="from Menu where pid=? order by mid";19         String hql="from Menu m inner join fetch m.users u where m.pid=? and u.uid=? order by m.mid";20         Query query=session.createQuery(hql);21         query.setLong(0, pid);22         query.setLong(1, 16L);23         List<Menu> list=query.list();24         for(Menu m:list){25             System.out.println(m.getMid()+"--"+m.getName());26 //            this.listMenu.add(m);27             res.add(m);28         }29         for(Menu m:list){30             Long tmp_pid=m.getMid();31             if(tmp_pid!=null){32                 vistTreeNodesByPid(tmp_pid,res);33             }34         }35     }

这样就轻松解决了这个问题。

 

递归解决根据父节点遍历权限树菜单的问题--------mysql数据中的树表