双向关联
- One-To-One
@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="passport_fk")
public Passport getPassport() {
...
}
@Entity
public 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
数据库中的一个树结构,对象的表现形式.
@Entity
public class TreeObject {
private int id;
private String name;
private TreeObject parent;
private List<TreeObject> children = new ArrayList<TreeObject>();
@Id
@GeneratedValue
public 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对象负责维持关系,也就是说我们用下面的方法就可以保存这些关系.
@Test
public 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也跟着保存了.
@Test
public 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
上一篇: css 设置下拉列表 select 样式
下一篇: 日期和枚举等字段类型的JPA映射