《Hibernate学习笔记十一》:树状结构设计

《Hibernate学习笔记十一》:树状结构设计

这是马士兵老师讲解Hibernate的一个作业题,树状结构设计,这是一个比较典型的例子,因此有必要写篇博文记录下。

树状结构的设计,它是在同一个类中使用了多对一(ManyToOne)和一对多(OneToMany).

在完成这个题目我们应该按照如下的步骤进行:

1、先思考数据库的模型应该是什么样的??

数据库中的模型应该如下:即存在id p_id

《Hibernate学习笔记十一》:树状结构设计_第1张图片

2、思考面向对象的模型,及如何来进行映射???

根据数据库中表的特点,对象应该有id name;由于此类的对象与对象之间是多对一(即多个孩子对应一个父节点)和一对多(即一个父节点可以有多个孩子)的关系,因此就存在一个自己的引用(parent)以及孩子的Set集合(children);

3、思考如何进行增删改查???

实体类

注意里面的@OneToMany和@ManyToOne

@Entity
public class Org {
    private int id;
    private String name;
    private Set<Org> children=new HashSet<Org>();//孩子集,即站在父节点的角度,这是一个一对多的关联关系
    private Org parent;//站在孩子的角度,这是一个多对一的关系
    @Id
    @GeneratedValue
    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;
    }
    @OneToMany(cascade={CascadeType.ALL},fetch=FetchType.EAGER)  //一对多的关联关系
    public Set<Org> getChildren() {
        return children;
    }
    public void setChildren(Set<Org> children) {
        this.children = children;
    }
    @ManyToOne
    @JoinColumn(name="parent_id")  //即在数据库的表Org的外键名为parent_id
    public Org getParent() {
        return parent;
    }
    public void setParent(Org parent) {
        this.parent = parent;
    }

}

这样就完成了数状结构的设计,这个实体类中用到了OneToMany和ManyToOne.

考虑数据库的增删改查(CURD)操作

先看Save

@Test
    public void testSave(){
        Org o=new Org();
        o.setName("总公司");

        Org o1=new Org();
        o1.setName("分公司1");

        Org o2=new Org();
        o2.setName("分公司2");

        Org o11=new Org();
        o11.setName("公司1下面的部门1");

        Org o12=new Org();
        o12.setName("公司1下面的部门2");

        Org o21=new Org();
        o21.setName("公司2下面的部门1");
        Org o22=new Org();
        o22.setName("公司2下面的部门2");
        //建立双向关系
        o.getChildren().add(o1);
        o.getChildren().add(o2);

        o1.getChildren().add(o11);
        o1.getChildren().add(o12);
        o2.getChildren().add(o22);
        o2.getChildren().add(o21);

        o1.setParent(o);
        o2.setParent(o);
        o11.setParent(o1);
        o12.setParent(o1);
        o21.setParent(o2);
        o22.setParent(o2);
        Session s=sessionFactory.getCurrentSession();
        s.beginTransaction();
        s.save(o);
        s.getTransaction().commit();

    }

测试结果如下:

《Hibernate学习笔记十一》:树状结构设计_第2张图片

再看Load,并打印输出这棵树

@Test
    public void testLoad(){
        testSave();
        Session s=sessionFactory.getCurrentSession();
        s.beginTransaction();
        Org org=(Org)s.get(Org.class, 1);//由于我们在@OneToMany(fetch=FetchType.EAGER),因此,就可以一下子将孩子节点全部取出来
        print(org,0);//输出
        s.getTransaction().commit();
    }
    private void print(Org org,int level) {
        String str="";
        for(int i=0;i<level;i++){
            str+="----";
        }
        System.out.println(str+org.getName());
        for(Org o:org.getChildren()){
            print(o,level+1);
        }
    }

打印输出的结果如下:

《Hibernate学习笔记十一》:树状结构设计_第3张图片

在load的过程中,我们在实体类中设置了@OneToMany(fetch=FetchType.EAGER),因此,就可以一下子将孩子节点全部取出来,如果不设置为EAGER,而是LAZY,则就是用到才会去取出来。

以上可以说是对OneToMany和ManyToOne的一个应用啦。

参考资料

1、马士兵《Hibernate学习视频》

你可能感兴趣的:(Hibernate,数据库,一对多,多对一,树状结构设计)