本文共 2937 字,大约阅读时间需要 9 分钟。
OneToMany关联将一个父Entity类与若干个子Entity类联系起来。
1. 双向关联
通常,OneToMany关联都有与之反向的ManyToOne关联对应,两者成组出现,这被称为双向关联。
双向关联中,可以从任何一个Entity类实例访问关联的另一个Entity类实例(通过get*()方法)。
在数据库模式中,也只需要常规地,在子Entity类(owning side)中设置外键关联父Entity类(mappedBy side)即可。
父Entity定义如下:
@Entity(name = "Person")public static class Person { @Id @GeneratedValue private Long id; @OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true) private Listphones = new ArrayList<>(); public Person() { } public Person(Long id) { this.id = id; } public List getPhones() { return phones; } public void addPhone(Phone phone) { phones.add( phone ); phone.setPerson( this ); } public void removePhone(Phone phone) { phones.remove( phone ); phone.setPerson( null ); }}
子Entity定义如下:
@Entity(name = "Phone")public static class Phone { @Id @GeneratedValue private Long id; @NaturalId @Column(unique = true) private String number; @ManyToOne private Person person; public Phone() { } public Phone(String number) { this.number = number; } public Long getId() { return id; } public String getNumber() { return number; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } @Override public boolean equals(Object o) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } Phone phone = (Phone) o; return Objects.equals( number, phone.number ); } @Override public int hashCode() { return Objects.hash( number ); }}子Entity类重写了equals()和hashCode()方法,是为了利用Phone类中的number的唯一性,通常不是必须的。
2. 单向关联
不过,双向关联并不是必须的,也可以只有其中一种关联,就是单向关联,这样只能从拥有(owning)关联的Entity类实例访问关联的另一个Entity类实例。
如果只有OneToMany关联,则在数据库模式中,首先在子Entity类对应的数据库表中无需外键,因为子Entity类实例根本不知道要关联谁。此外,还额外需要一个中间表,以表示两者的关联关系。因为,在OneToMany关联的父Entity类(owning side)对应的数据库表中,是无法表示这种关联关系的。
父Entity定义如下:
@Entity(name = "Person")public static class Person { @Id @GeneratedValue private Long id; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) private List子Entity定义如下:phones = new ArrayList<>(); public Person() { } public List getPhones() { return phones; }}
@Entity(name = "Phone")public static class Phone { @Id @GeneratedValue private Long id; private String number; public Phone() { } public Phone(String number) { this.number = number; } public Long getId() { return id; } public String getNumber() { return number; }}数据库模式中的中间表如下:
CREATE TABLE Person_Phone ( Person_id BIGINT NOT NULL , phones_id BIGINT NOT NULL)单向关联在删除子Entity类实例的操作中,执行效率非常低下。因为,在持久化的操作过程中,首先要删除父Entity类实例关联的所有子Entity类实例,然后再重新插入尚未被删除的子Entity类实例。
转载地址:http://anlai.baihongyu.com/