zoukankan      html  css  js  c++  java
  • 026 hibernate操作树形结构

    树形结构:也就是目录结构,有父目录、子目录、文件等信息,而在程序中树形结构只是称为节点。

             一棵树有一个根节点,而根节点也有一个或多个子节点,而一个子节点有且仅有一个父节点(当前除根节点外),而且也存在一个或多个子节点。

             也就是说树形结构,重点就是节点,也就是我们需要关心的节点对象。

             节点:一个节点有一个ID、一个名称、它所属的父节点(根节点无父节点或为null),有一个或多的子节点等其它信息。

    Hibernate将节点抽取出成实体类,节点相对于父节点是“多对一”映射关系,节点相对于子节点是“一对多”映射关系。  

    节点实体类:

    /** * 节点*/
    
    public class Node {
    
        private int id; //标识符
        private String name; //节点名称 
        private int level; //层次,为了输出设计   
        private boolean leaf; //是否为叶子节点,这是为了效率设计,可有可无
        //父节点:因为多个节点属于一个父节点,因此用hibernate映射关系说是“多对一”
        private Node parent;
        //子节点:因为一个节点有多个子节点,因此用hibernate映射关系说是“一对多”
        private Set children;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getLevel() {
            return level;
        }
    
        public void setLevel(int level) {
            this.level = level;
        }
    
        public boolean isLeaf() {
            return leaf;
        }
    
        public void setLeaf(boolean leaf) {
            this.leaf = leaf;
        }
    
        public Node getParent() {
            return parent;
        }
    
        public void setParent(Node parent) {
            this.parent = parent;
        }
    
        public Set getChildren() {
            return children;
        }
    
        public void setChildren(Set children) {
            this.children = children;
        }
    
    }

    节点映射文件:

    <hibernate-mapping>
        <class name="com.wjt276.hibernate.Node" table="t_node">
           <id name="id" column="id">
                <generator class="native"/>
            </id>
            <property name="name"/>
            <property name="level"/>
            <property name="leaf"/>
    <!— 一对多:加入一个外键,参照当前表t_node主键
        而属性parent类型为Node,也就是当前类,则会在同一个表中加入这个字段,参照这个表的主键-->
            <many-to-one name="parent" column="pid"/>
        <!-- <set>标签是映射一对多的方式,加入一个外键,参照主键。-->
            <set name="children" lazy="extra" inverse="true">
                <key column="pid"/>
                <one-to-many class="com.wjt276.hibernate.Node"/>
            </set>    
        </class>
    </hibernate-mapping>

    测试代码:

    public class NodeTest extends TestCase {
    
        //测试节点的存在
    
        public void testSave1(){
            NodeManage.getInstanse().createNode("F:\JAVA\JavaProject\hibernate\hibernate_training_tree");
    
        }
    
        //测试节点的加载
    
        public void testPrintById(){
            NodeManage.getInstanse().printNodeById(1);
        }
    
    }

    相应的类代码:

    public class NodeManage {
    
        private static NodeManage nodeManage= new NodeManage(); 
        private NodeManage(){}//因为要使用单例,所以将其构造方法私有化
    
       
        //向外提供一个接口
        public static NodeManage getInstanse(){
            return nodeManage;
        }
    
     
    
        /**
         * 创建树
         * @param filePath 需要创建树目录的根目录
         */
        public void createNode(String dir) {
            Session session = null;   
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();
             
                File root = new File(dir);
                //因为第一个节点无父节点,因为是null
    
                this.saveNode(root, session, null, 0);      
                session.getTransaction().commit();
            } catch (HibernateException e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                HibernateUtils.closeSession(session);
            }
        }
        /**
         * 保存节点对象至数据库
         * @param file 节点所对应的文件
         * @param session session
         * @param parent 父节点
         * @param level 级别
         */
        public void saveNode(File file, Session session, Node parent, int level) {      
            if (file == null || !file.exists()){
               return;
            }
         
            //如果是文件则返回true,则表示是叶子节点,否则为目录,非叶子节点
            boolean isLeaf = file.isFile();     
            Node node = new Node();
            node.setName(file.getName());
            node.setLeaf(isLeaf);
            node.setLevel(level);
            node.setParent(parent);
            session.save(node);     
            //进行循环迭代子目录
            File[] subFiles = file.listFiles();
            if (subFiles != null && subFiles.length > 0){
                for (int i = 0; i < subFiles.length ; i++){
                    this.saveNode(subFiles[i], session, node, level + 1);
                }
            }
        }
        /**
         * 输出树结构
         * @param id
         */
        public void printNodeById(int id) {
            Session session = null;      
            try {
                session = HibernateUtils.getSession();
                session.beginTransaction();          
                Node node = (Node)session.get(Node.class, 1);          
                printNode(node);       
                session.getTransaction().commit();
            } catch (HibernateException e) {
               e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                HibernateUtils.closeSession(session);
            }      
        }  
        private void printNode(Node node) {
            if (node == null){
                return;
            }      
            int level = node.getLevel();    
            if (level > 0){
                for (int i = 0; i < level; i++){
                    System.out.print("  |");
                }
                System.out.print("--");            
            }
            System.out.println(node.getName() + (node.isLeaf() ? "" : "[" + node.getChildren().size() + "]"));
       
            Set children = node.getChildren();
            for (Iterator iter = children.iterator(); iter.hasNext(); ){
                Node child = (Node)iter.next();
                printNode(child);
            }
        }
    }
  • 相关阅读:
    Begin Example with Override Encoded SOAP XML Serialization
    State Machine Terminology
    How to: Specify an Alternate Element Name for an XML Stream
    How to: Publish Metadata for a WCF Service.(What is the Metadata Exchange Endpoint purpose.)
    Beginning Guide With Controlling XML Serialization Using Attributes(XmlSerializaiton of Array)
    Workflow 4.0 Hosting Extensions
    What can we do in the CacheMetaData Method of Activity
    How and Why to use the System.servicemodel.MessageParameterAttribute in WCF
    How to: Begin Sample with Serialization and Deserialization an Object
    A Test WCF Service without anything of config.
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4080750.html
Copyright © 2011-2022 走看看