氟塑料离心泵www.buybeng.com

jquery教程http://www.software8.co/wzjs/jquery/

对于java的树形结构的抽象与拓展

近来几日,在学习hibernate,在做练习的时候,想做一个树形结构出来,比如组织架构,于是开始动手去尝试,首先是利用hibernate自己的方式做一棵树,于是开始动手构建persisten object,代码如下:

 

Java代码  
  1. package com.zq.po;  
  2.   
  3. import javax.persistence.*;  
  4. import java.util.List;  
  5.   
  6.   
  7. @Entity  
  8. @Table(name = "t_modual")  
  9. public class Modual2 {  
  10.     private long dbid;  
  11.     private String nane;  
  12.     private String url;  
  13.     private Modual2 parent;  
  14.     private List<Modual2> children;  
  15.   
  16.     public Modual2() {  
  17.     }  
  18.     @Id  
  19.     @GeneratedValue(strategy = GenerationType.IDENTITY)  
  20.     public long getDbid() {  
  21.         return dbid;  
  22.     }  
  23.   public void setDbid(long dbid) {  
  24.         this.dbid = dbid;  
  25.     }  
  26.   
  27.     public String getNane() {  
  28.         return nane;  
  29.     }  
  30.   
  31.     public void setNane(String nane) {  
  32.         this.nane = nane;  
  33.     }  
  34.   
  35.     public String getUrl() {  
  36.         return url;  
  37.     }  
  38.   
  39.     public void setUrl(String url) {  
  40.         this.url = url;  
  41.     }  
  42.     @ManyToOne  
  43.     @JoinColumn(name = "parent_id")  
  44.     public Modual2 getParent() {  
  45.         return parent;  
  46.     }  
  47.     public void setParent(Modual2 parent) {  
  48.        this.parent = parent;  
  49.     }  
  50.     @OneToMany(mappedBy = "parent",cascade = CascadeType.ALL,fetch = FetchType.EAGER)  
  51.     public List<Modual2> getChildren() {  
  52.         return children;  
  53.     }  
  54.   
  55.     public void setChildren(List<Modual2> children) {  
  56.         this.children = children;  
  57.     }  
  58. }  

       然后利用代码声生成结构,但是这样一来,生成的表中,parent_id是强制关联自己表的主键的,感觉这样不是很灵活,于是就想着,把外键约束去掉,转而在程序里控制好,这样灵活性提高了。想想在工作中遇到的树形结构的表设计中,也没有加入外键约束,所以我就开始构建一个没有外键约束的树形结构。

      经过思考,我决定使用如下的方式实现:抽象出一个BaseTree来,里面有主键,父亲节点的ID,父亲节点的对象和儿子节点的集合,这基本上是所有树形结构都共有的特性,所以抽象出来,让其他的树去继承,然后让程序员更加关注本树的业务字段。抽象出来的BaseTree代码如下:   

 

Java代码  
  1. package com.zq.po;  
  2.   
  3. import java.util.List;  
  4.   
  5.   
  6. public class BaseTree<T> {  
  7.     private long dbid;  
  8.     private long parentId;  
  9.     private T parent;  
  10.     private List<T> children;  
  11.   
  12.    public long getDbid() {  
  13.         return dbid;  
  14.     }  
  15.   
  16.     public void setDbid(long dbid) {  
  17.         this.dbid = dbid;  
  18.     }  
  19.   
  20.     public long getParentId() {  
  21.         return parentId;  
  22.     }  
  23.   
  24.     public void setParentId(long parentId) {  
  25.         this.parentId = parentId;  
  26.     }  
  27.   
  28.     public T getParent() {  
  29.         return parent;  
  30.     }  
  31.   
  32.     public void setParent(T parent) {  
  33.         this.parent = parent;  
  34.     }  
  35.   
  36.     public List<T> getChildren() {  
  37.         return children;  
  38.   }  
  39.   
  40.     public void setChildren(List<T> children) {  
  41.         this.children = children;  
  42.     }  
  43. }  

         然后再创建一棵树,让他继承BaseTree,但是需要重写主键和父节点ID这两个属性,因为需要把他们映射到数据库里面去,代码如下:

 

Java代码  
  1. package com.zq.po;  
  2.   
  3. import javax.persistence.*;  
  4. import java.util.List;  
  5.   
  6.   
  7. @Entity  
  8. @Table(name="t_orga")  
  9. public class Organization  extends BaseTree<Organization>{  
  10.     private long dbid;  
  11.     private long parentId;  
  12.     private String name;  
  13.     private int count;  
  14.     //private Organization parent;  
  15.     //private List<Organization> children;  
  16.   
  17.     public Organization() {  
  18.     }  
  19.     @Id  
  20.     @GeneratedValue(strategy = GenerationType.IDENTITY)  
  21.     public long getDbid() {  
  22.         return dbid;  
  23.     }  
  24.   
  25.     public void setDbid(long dbid) {  
  26.         this.dbid = dbid;  
  27.     }  
  28.   
  29.     public String getName() {  
  30.         return name;  
  31.     }  
  32.   
  33.     public void setName(String name) {  
  34.         this.name = name;  
  35.     }  
  36.   
  37.     public int getCount() {  
  38.         return count;  
  39.     }  
  40.   
  41.     public void setCount(int count) {  
  42.         this.count = count;  
  43.     }   
  44.     public long getParentId() {  
  45.         return parentId;  
  46.     }  
  47.   
  48.     public void setParentId(long parentId) {  
  49.         this.parentId = parentId;  
  50.     }  
  51.     /*@Transient 
  52.     public Organization getParent() { 
  53.         return parent; 
  54.     } 
  55.  
  56.     public void setParent(Organization parent) { 
  57.         this.parent = parent; 
  58.     } 
  59.     @Transient 
  60.     public List<Organization> getChildren() { 
  61.         return children; 
  62.     } 
  63.  
  64.     public void setChildren(List<Organization> children) { 
  65.         this.children = children; 
  66.     }*/  
  67. }  

      这样,模型就出来了,创建出来的表结构如下图:完全没有了外键约束符合要求:

       

 

        虽然是模型和表都整出来了,但是有一个问题,当我们把所有的树节点都查询出来的时候,他们自身只有一个父节点的ID,想访问他的父节点或者是孩子节点,需要拿着该节点的主键查孩子节点或者拿着patentId查父亲节点,很是麻烦,于是就想着整一个工具类,把全查出来的节点的父亲和儿子都匹配上,目前只是完成了全部节点的匹配,以后还会完成某一个节点的匹配。建了一个工具类,代码如下:

 

Java代码  
  1. public class BaseTreeUtil extends BaseTree {  
  2.     private BaseTree baseTree1;  
  3.     private BaseTree baseTree2;  
  4.   
  5.     public List allInit(List param)  {  
  6.         //找老子  
  7.         for (int i = 0; i < param.size(); i++) {  
  8.             baseTree1 = (BaseTree) param.get(i);  
  9.             if (baseTree1.getParentId() == -1) {  
  10.                 break;  
  11.             } else {  
  12.                 for (int j = 0; j < param.size(); j++) {  
  13.                     baseTree2 = (BaseTree) param.get(j);  
  14.                     if (baseTree2.getDbid() == baseTree1.getParentId()) {  
  15.                         baseTree2.setParent(baseTree1);  
  16.                     }  
  17.                 }  
  18.             }  
  19.         }  
  20.         //找儿子  
  21.         for (int k = 0; k < param.size(); k++) {  
  22.             baseTree1 = (BaseTree) param.get(k);  
  23.             List<BaseTree> sons = new ArrayList<BaseTree>();  
  24.             for (int l = 0; l < param.size(); l++) {  
  25.                 baseTree2 = (BaseTree) param.get(l);  
  26.                 if (baseTree1.getDbid() == baseTree2.getParentId()) {  
  27.                     sons.add(baseTree2);  
  28.                 }  
  29.             }  
  30.             baseTree1.setChildren(sons);  
  31.         }  
  32.         return param;  
  33.     }  
  34.   
  35. }  

      这样就是把查出来的节点做循环,先是给每个节点的找到父亲节点,然后在给每个节点去找儿子节点。

     附上一段测试代码(片段):

Java代码  
  1. public static void print(Organization orga, int level) {  
  2.      String show = "";  
  3.      for (int i = 0; i < level; i++) {  
  4.          show += "----";  
  5.      }  
  6.      System.out.println(show + orga.getName());  
  7.      level++;  
  8.      for (Organization children : orga.getChildren()) {  
  9.          print(children, level);  
  10.      }  
  11.  }  
  12.  @Test  
  13.  public void testSelect02() {  
  14.      Session session = this.before();  
  15.      Transaction tx = session.beginTransaction();  
  16.   
  17.      Query query =session.createQuery("from Organization ");  
  18.      List<Organization> list=query.list();  
  19.      List list2= new BaseTreeUtil().allInit(list);  
  20.   
  21.      print((Organization)list2.get(0), 0);  
  22.   
  23.      this.after(tx);  
  24.   
  25.   
  26.  }  

    不好意思,忘记附上表的数据了,补上:



 
  最后测试的结果如下:

 

 

 到此,基本的功能都已经实现了,剩下需要做的有如下几个:

        1、晚上BaseTreeUtil的功能

        2、把以上内容应用到DAO层的编写中,整合到spring进行测试

  后续工作的总结写在下次日志中。
原文链接:
http://www.software8.co/wzjs/java/3335.html

posted on 2013-03-13 17:33 你爸是李刚 阅读(1922) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 
<2013年3月>
242526272812
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿

随笔档案

文章档案

技术网站

行业网站

搜索

最新评论

阅读排行榜

评论排行榜

站长网 氟塑料离心泵 注塑机 液晶广告机