关于在Hibernate中高效的处理Tree结构

1:

我们都知道Tree结构是RDBMS的一个死穴。
可是我们常常在实际中碰到这样的结构,比如部门结构,栏目结构....
原来用JDBC来处理这些树结构比较简单,只要解决一个Select抓回一棵树的问题这个关键问题,然后排序一下就搞定了。
在Hibernate中,如何来高效的完成这些工作呢?

以下是一个典型的父子关系的mapping
java代码: 


<class name="test.TreeNode" table="tree">
                <id name="id" column="nodeId" type="long" unsaved-value="null">
                        <generator class="identity"/>
                </id>
                <many-to-one name="parent" column="parentId"  class="test.TreeNode" cascade="save-update" access="field"/>
                <property name="xxxx" column="xxxx" type="long" not-null="true"/>
        </class>



但是这样的结构,如果要获得某子节点下所有的节点,则要多个SQL(树有几层就调几次)

有更高效的实现办法么?

2:

我做的時候只是先查出第一層,然後對這個根做一個遞歸就可以呀
java代码: 


        private void buildChild(FolderListForm folderListForm, DocPO docPO)
                throws Exception {
                Collection children = docPO.getChildren();
                int order = 1;
                for (java.util.Iterator it = children.iterator(); it.hasNext();) {
                        DocPO child = (DocPO) it.next();
                        DocTreeNodeForm docTreeNodeForm = new DocTreeNodeForm();
                        BeanUtils.copyProperties(docTreeNodeForm, child);
                        folderListForm.getDocTreeNodeFormList().add(docTreeNodeForm);
                        buildChild(folderListForm, child);
                }
        }

 

3:

请注意parent和children都映射到同一个字段fk_parend_id,对树各种操作居然能成功,不得不佩服Hibernate的强悍!

java代码: 


import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Stack;
/**
* @hibernate.class table="CATS"
*  dynamic-update="true"
* dynamic-insert="true"
*
*/

public class Cat {
        private Long id; // identifier
        private List children = new ArrayList();
        private Cat parent;
                     
/**
        * @hibernate.id
        * generator-class="native"
        * column="cat_id"
        */

        public Long getId() {
                return id;
        }
        private void setId(Long id) {
                this.id = id;
        }
        public Cat addChildren(Cat child) {
                children.add(child);
                return this;
        }
       
/**
        * @hibernate.list
        * cascade="all"
        * lazy="true"
        * @hibernate.collection-key
        * column="fk_parent_id"
        * @hibernate.collection-one-to-many
        * class="com.nosqldb.bo.Cat"
       
        * @hibernate.collection-index
        * column="index_parent_id"
        */

        public List getChildren() {
                return children;
        }
       
/**
        * @param children The children to set.
        */

        public void setChildren(List children) {
                this.children = children;
        }
       
/**
        * @return
        * @hibernate.many-to-one
        * column="fk_parent_id"
        * class="com.nosqldb.bo.Cat"
        * cascade="all"
        */

        public Cat getParent() {
                return parent;
        }
       
/**
        * @param parent The parent to set.
        */

        public void setParent(Cat parent) {
                this.parent = parent;
        }
       
/**
        * 树形遍历
        * 不用递归,用堆栈.
        * 这里只是做为例子,本人不建议把业务逻辑封装在Entity层.
                */

        public List getVisitResults() {
                List l = new ArrayList();
                Stack s = new Stack();
                s.push(this);
                while (s.empty() == false) {
                   Cat c = (Cat) s.pop();
                   l.add(c);
                   List children = c.getChildren();
                      if (children != null) {
                         for (int i = 0; i <  hildren.size(); i++)   {
                        Cat cat = (Cat) children.get(i);
                        s.push(cat);
                         }//end for
                     }//end if
                }//end while
                return l;
        }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值