递归解决根据父节点遍历权限树菜单的问题--------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 }
这样就轻松解决了这个问题。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。