双向关联
- One-To-One??
????
@Entitypublic class Customer implements Serializable { @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name="passport_fk") public Passport getPassport() { ... }@Entitypublic class Passport implements Serializable { @OneToOne(mappedBy = "passport") public Customer getOwner() { ...}?
在双向关联中, 有且仅有一端是作为主体(owner)端存在的:主体端负责维护联接列(即外键FK). 对于不需要维护这种关系的从表则通过mappedBy属性进行声明. mappedBy的值指向主体的关联属性. 在上面这个例子中,mappedBy的值为 passport. 最后,不必也不能再在被关联端(owned side)定义联接列了,因为已经在主体端进行了声明.如果在主体没有声明@JoinColumu,系统自动进行处理: 在主表(owner table)中将创建联接列, 列名为:主体的关联属性名+下划线+被关联端的主键列名. 在上面这个例子中是passport_id, 因为Customer中关联属性名为passport, passport的主键是id.
?
注意:
??? 只要有双向关联关系,必设mppedBy
??? ManyToOne关系中默认的fetch是?FetchType.EAGER
??? OneToMany关系中默认的fetch是?FetchType.LAZY
?
?
?
数据库中的一个树结构,对象的表现形式.
?
?
@Entitypublic class TreeObject {private int id;private String name;private TreeObject parent;private List<TreeObject> children = new ArrayList<TreeObject>();@Id@GeneratedValuepublic int getId() {return id;}@ManyToOne@JoinColumn(name="parent_id")public TreeObject getParent() {return parent;}@OneToMany(cascade=CascadeType.ALL,mappedBy="parent")@OrderBy("name ASC")public List<TreeObject> getChildren() {return children;} ....................?
生成的表结构:
?
?
create table TreeObject ( id integer not null auto_increment, name varchar(255), parent_id integer, primary key (id) ) alter table TreeObject add index FK95A4309DA50A61ED (parent_id), add constraint FK95A4309DA50A61ED foreign key (parent_id) references TreeObject (id)
?
?
??? ManyToOne和OneToMany双向关系上,在OneToMany端设置mappedBy,表示主体端是Many端,关系的主导是One端的getChildren集合中的TreeObject的parent对象负责维持关系,也就是说我们用下面的方法就可以保存这些关系.
?
@Testpublic void testSaveTreeObject() {TreeObject o = new TreeObject();o.setName("总公司");TreeObject o1 = new TreeObject();o1.setName("分公司1");TreeObject o2 = new TreeObject();o2.setName("分公司2");o1.setParent(o);o2.setParent(o);Session s = sessionFactory.openSession();s.beginTransaction();s.save(o);s.save(o1);s.save(o2);s.getTransaction().commit();s.close();}?
这段代码和上面的效果是一样的,因为@OneToMany(cascade=CascadeType.ALL,mappedBy="parent"),
CascadeType.ALL保存parent对象时,children也跟着保存了.
@Testpublic void testSaveTreeObject() {TreeObject parent = new TreeObject();parent.setName("总公司");TreeObject child1 = new TreeObject();child1.setName("分公司1");TreeObject child2 = new TreeObject();child2.setName("分公司2");child1.setParent(parent);child2.setParent(parent);parent.getChildren().add(child1);parent.getChildren().add(child2);Session s = sessionFactory.openSession();s.beginTransaction();s.save(parent);s.getTransaction().commit();s.close();}?
??
数据库表中生成三条记录:
id???? name????? ?parent_id
1????? 总公司????? null
2????? 分公司1??? 1
3????? 分公司2??? 1
?
?
?