本文共 5129 字,大约阅读时间需要 17 分钟。
package cn.edu.hpu.treeStruct;import java.util.HashSet;import java.util.Set;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.ManyToOne;import javax.persistence.OneToMany;@Entitypublic class Org { private int id; private String name; private Set如何来理解这张表,我们假设这是三张表(都是id、name)。 A、B、C假设B的父亲是A,B的孩子是C,B通过parent_id去找父亲A, C通过parent_id去找父亲B。只不过是多张表合成一张表。然后每一个人 的parent_id都去参考另外一条记录了,也就是参考自身这张表。是 一对多和多对一的双向关联关系。 测试,输出的建表sql语句: alter table Org drop foreign key FK136C4424F8DF5 drop table if exists Org create table Org ( id integer not null auto_increment, name varchar(255), parent_id integer, primary key (id) ) alter table Org add index FK136C4424F8DF5 (parent_id), add constraint FK136C4424F8DF5 foreign key (parent_id) references Org (id) 添加测试:children=new HashSet (); 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 public Set getChildren() { return children; } public void setChildren(Set children) { this.children = children; } @ManyToOne public Org getParent() { return parent; } public void setParent(Org parent) { this.parent = parent; } }
@Testpublic void testTreeAdd(){ 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"); o.getChildren().add(o1); o.getChildren().add(o2); o.getChildren().add(o11); o.getChildren().add(o12); o11.setParent(o1); o12.setParent(o1); o1.setParent(o); o2.setParent(o); //可以先存父亲,再存孩子,也可以让Org的Childern设置CascadeType.ALL //这里用的是设置CascadeType.ALL,所以只存父亲就可以了 sessionFactory=new AnnotationConfiguration().configure().buildSessionFactory(); Session session=sessionFactory.openSession(); session.beginTransaction(); session.save(o); session.getTransaction().commit(); session.close();}输出的sql语句: Hibernate: insert into Org (name, parent_id) values (?, ?) Hibernate: insert into Org (name, parent_id) values (?, ?) Hibernate: insert into Org (name, parent_id) values (?, ?) Hibernate: insert into Org (name, parent_id) values (?, ?) Hibernate: insert into Org (name, parent_id) values (?, ?) Hibernate: update Org set name=?, parent_id=? where id=? Hibernate: update Org set name=?, parent_id=? where id=? 结果: id name parent_id 1 总公司 null 2 分公司1下公司1 5 3 分公司1下公司2 5 4 分公司2 1 5 分公司1 1 读取测试(用递归): 简单的方式就是Org的Childern设置fetch=FetchType.EAGER,最好的方式是递归。 首先用fetch=FetchType.EAGER测试:
@Testpublic void testTreeLoad(){ sessionFactory=new AnnotationConfiguration().configure().buildSessionFactory(); Session session=sessionFactory.openSession(); session.beginTransaction(); Org o =(Org) session.load(Org.class,1); Treeprint(o); session.getTransaction().commit(); session.close();}private void Treeprint(Org o) { System.out.println(o.getName()); for(Org child:o.getChildren()){ Treeprint(child); }}测试结果: Hibernate: select org0_.id as id0_1_, org0_.name as name0_1_, org0_.parent_id as parent3_0_1_, children1_.parent_id as parent3_0_3_, children1_.id as id3_, children1_.id as id0_0_, children1_.name as name0_0_, children1_.parent_id as parent3_0_0_ from Org org0_ left outer join Org children1_ on org0_.id=children1_.parent_id where org0_.id=? Hibernate: select children0_.parent_id as parent3_0_1_, children0_.id as id1_, children0_.id as id0_0_, children0_.name as name0_0_, children0_.parent_id as parent3_0_0_ from Org children0_ where children0_.parent_id=? Hibernate: select children0_.parent_id as parent3_0_1_, children0_.id as id1_, children0_.id as id0_0_, children0_.name as name0_0_, children0_.parent_id as parent3_0_0_ from Org children0_ where children0_.parent_id=? Hibernate: select children0_.parent_id as parent3_0_1_, children0_.id as id1_, children0_.id as id0_0_, children0_.name as name0_0_, children0_.parent_id as parent3_0_0_ from Org children0_ where children0_.parent_id=? Hibernate: select children0_.parent_id as parent3_0_1_, children0_.id as id1_, children0_.id as id0_0_, children0_.name as name0_0_, children0_.parent_id as parent3_0_0_ from Org children0_ where children0_.parent_id=? 总公司 分公司1 分公司1下公司2 分公司1下公司1 分公司2 如何展现成树状?
@Testpublic void testTreeLoad(){ sessionFactory=new AnnotationConfiguration().configure().buildSessionFactory(); Session session=sessionFactory.openSession(); session.beginTransaction(); Org o =(Org) session.load(Org.class,1); Treeprint(o,0); session.getTransaction().commit(); session.close();}private void Treeprint(Org o,int level) { //level是构建树状前的缩进 String preStr=""; for(int i=0;i测试结果: 总公司 ----分公司2 ----分公司1 --------分公司1下公司2 --------分公司1下公司1
如果这棵树非常大我们用EAGER就不合适了,需要把它去掉了,什么时候需要(get)才从数据库拿出。
尊重开源精神,尊重劳动成果,转载请注明出处: