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);
        }
    }
}
原文地址:https://www.cnblogs.com/crazylqy/p/4080750.html