双向关联

  1. 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

 

 

 

你可能感兴趣的:(jpa)