关闭

Hibernate中的Entity类之间的OneToMany关联

标签: hibernateentityassociate数据库OneToMany
571人阅读 评论(0) 收藏 举报

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 List<Phone> phones = new ArrayList<>();

    public Person() {
    }

    public Person(Long id) {
        this.id = id;
    }

    public List<Phone> 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<Phone> phones = new ArrayList<>();

    public Person() {
    }

    public List<Phone> getPhones() {
        return phones;
    }
}

子Entity定义如下:

@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类实例。


1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:285782次
    • 积分:6023
    • 等级:
    • 排名:第4166名
    • 原创:317篇
    • 转载:0篇
    • 译文:0篇
    • 评论:32条
    文章分类
    最新评论