Hibernate树型结构的算法,附源码! (dhj1)

1:

代码还没调试过,刚写出来!

java代码: 

package com.yours.tree;

import java.util.List;
import java.util.Iterator;
import org.apache.log4j.Logger;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.Session;

import com.yours.datamodel.hibernate.HibernateSession;
import com.yours.admin.jdo.Auth;




/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: </p>
* @author 段洪杰
* @version 1.0
*/


public class TreeAuth {

  private static Logger log = Logger.getLogger(TreeAuth.class);

 
/**
   * 取根叶
   * @return Iterator
   */


  public Iterator getRoot() {
    Iterator iterator = null;
    String sql = "from Auth as auth where auth.parentid is null";
    try {
      Session session = HibernateSession.currentSession();
      Query query = session.createQuery(sql);
      iterator = query.iterate();
    }
    catch (HibernateException e) {
      log.error(e);
    }

    return iterator;
  }

 
/**
   * 存根叶
   * @param Object Leaf
   */


  public void setRoot(Auth auth) {
    try {
      Session session = HibernateSession.currentSession();
      HibernateSession.currentTransaction();
      session.save(auth);
      session.flush();
    }
    catch (HibernateException e) {
      log.error(e);
    }

  }

 
/**
   * 取子叶
   * @param parentLeaf Leaf
   * @return Iterator
   */


  public Iterator getChild(String parentid) {
    Iterator iterator = null;
    String sql = "from Auth as auth where auth.parentid= '" + parentid + "'";
    try {
      Session session = HibernateSession.currentSession();
      Query query = session.createQuery(sql);
      iterator = query.iterate();
    }
    catch (HibernateException e) {
      log.error(e);
    }
    return iterator;
  }

 
/**
   * 取子叶数
   * @param parentLeaf Leaf
   * @return int
   */


  public int getChildCount(String parentid) {
    int count = 0;
    String sql = "select count(*) from Auth as auth where auth.parentid=
'" +
        parentid + "'
";
    try {
      Session session = HibernateSession.currentSession();
      count = ( (Integer) session.iterate(sql).next()).intValue();
    }
    catch (HibernateException e) {
      log.error(e);
    }
    return count;

  }

 
/**
   * 存子叶
   * @param parentLeaf Leaf
   */


  public void setChild(Auth auth, String parentid) {
    auth.setParentid(parentid);
    try {
      Session session = HibernateSession.currentSession();
      HibernateSession.currentTransaction();
      session.save(auth);
      session.flush();
    }
    catch (HibernateException e) {
      log.error(e);
    }

  }

 
/**

   *
   * 删除该叶和它的子叶
   * @param leaf Leaf
   */


  public void deleteBranch(Auth auth) {
    try {
      Session session = HibernateSession.currentSession();
      HibernateSession.currentTransaction();
      String id = auth.getId();
      Iterator iterator = getChild(id);
      if (iterator != null) {
        while (iterator.hasNext()) {
          Auth auth1 = (Auth) iterator.next();
          deleteBranch(auth1);
        }
      }
      session.delete(auth);
      session.flush();
    }
    catch (HibernateException e) {
      log.error(e);
    }
  }


}

2:

我不明白,HB还要这种方法吗??
用 composite 模式也可以呀..
直接用关系就可以了(HB对于各对象的关系管理非常到位).
下面代码没有经过测试,只是用txt工具随手写的.
java代码: 


/**
* @hibernate.class
*  table="tree"
*/

public class Component {
       
        private long id;

        private String name;
       
        private Component parent;
       
        private Set children=new HashSet();
       
        private Component(){}
       
        public Component(String name){
                this.name=name;
        }
       
       
/**
        * @hibernate.id
        *  generator-class = "native"
        */
 
        public getId(){
                return Id;
        }
       
        private setId(long id){
                this.id=id;
        }
       
       
/**
        * @hibernate.property
        *  length="64"
        *  not-null="true"
        */

        public String getName(){
                return name;
        }
       
        public void setName(String name){
                this.name=name;
        }
       
       
/**
        * 获得父节点
        * @hibernate.many-to-one
        *  column="parentId"
        */

        public Component getParent(){
                return parent;
        }
       
        public void setParent(Component parent){
                this.parent=parent;
        }
       
       
/**
        * 获得子节点
        * @hibernate.set
        *  lazy = "true"
        *  table = "tree"
        * @hibernate.collection-key
        *  column = "parentId"
        * @hibernate.collection-one-to-many
        *  class = "Component"
        */

        public Set getChildren(){
                return children;
        }
       
        private void setChildren(Set children){
                this.children=children;
        }
       
        public void addChild(Component child){
                children.add(child);
        }
       
        public void removeChild(Component child){
                childrent.remove(child);
        }
       
        public void clearChildren(){
                children=new HashSet();
        }
}

3:

虽然对hibernate不熟,但是使用过几次JTree,楼上有几个方法我觉得有些草率,大概是随手写的缘故吧。
此外,既然children使用Hashset,是否Component类也应该考虑实现equals方法和hashcode方法呢?

java代码: 



   public void addChild(Component child){
      children.add(child);
      child.setParent(this);
   }

   public boolean removeChild(Component child){
        return children.remove(child);
   }

   public void clearChildren(){
        children.clear();
   }


4:

楼上说得对(但我觉得没有多大影响,除非对象用来作Map的key,就一定要用实现equals,hashcode,因为一般人都不会把同一条记录放在同一个set,当然每个类都实现equals,hashcode,toString是最好).

其实我上面实现的并不好,因为是与楼主方法的一个变种,所以它还是会每次都向数据库发射SQL(取children或者其它的),效率问题不是最好.

补:
看了HashSet的源码后,发现它是用一个HashMap来管理的,把add的对象作为key.不过由于key与value没有多大关系,我觉得可以不实现equals与hashcode.不过还是实现为好.

5:

使用composite模式,也是一个不错的方法.

不过, 我认为我的方法会有更好的性能,比如取一个子叶,我的方法是一层一层的取的,有更好的灵活性和可以减少内存占用.

当然对有的人来说,我建议直接用composite模式.那样更OOP一些.但是我更喜欢我的方法!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值