欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

双向关联

程序员文章站 2022-01-18 22:51:05
...
  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