本文共 7817 字,大约阅读时间需要 26 分钟。
Hibernate中的Entity类之间的ManyToMany关联,必须在数据库模式中有一个中间连接表,其中的外键作为两个实体表之间的桥梁;而实体表中没有外键。
1. ManyToMany单向关联
任选一个实体类作为owning side,设置关联如下:
@Entity(name = "Person")public static class Person { @Id @GeneratedValue private Long id; @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private List addresses = new ArrayList<>(); public Person() { } public List getAddresses() { return addresses; }}在另一个实体类中不设置任何关联,如下:
@Entity(name = "Address")public static class Address { @Id @GeneratedValue private Long id; private String street; private String number; public Address() { } public Address(String street, String number) { this.street = street; this.number = number; } public Long getId() { return id; } public String getStreet() { return street; } public String getNumber() { return number; }}单向关联中,没有关联实体类的概念。
单向关联中,删除被关联对象时,首先删除所有被关联的对象,然后再重新插入没有被删除的对象,存在性能瓶颈。
2.ManyToMany双向关联
在ManyToMany双向关联中,两个实体类可以互为父子类。任选其中一个作为父实体类(owning side),其中定义集合对象引用子实体类,子实体类(inverse side)方给出(mappedBy="...")指向父实体类。
父实体类(owning side)定义如下:
@Entity(name = "Person")public static class Person { @Id @GeneratedValue private Long id; @NaturalId private String registrationNumber; @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) private List addresses = new ArrayList<>(); public Person() { } public Person(String registrationNumber) { this.registrationNumber = registrationNumber; } public List getAddresses() { return addresses; } public void addAddress(Address address) { addresses.add( address ); address.getOwners().add( this ); } public void removeAddress(Address address) { addresses.remove( address ); address.getOwners().remove( this ); } @Override public boolean equals(Object o) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } Person person = (Person) o; return Objects.equals( registrationNumber, person.registrationNumber ); } @Override public int hashCode() { return Objects.hash( registrationNumber ); }}
子实体类(inverse side)定义如下:
@Entity(name = "Address")public static class Address { @Id @GeneratedValue private Long id; private String street; private String number; private String postalCode; @ManyToMany(mappedBy = "addresses") private List3.ManyToMany双向关联与两个OneToMany双向关联的等价替换owners = new ArrayList<>(); public Address() { } public Address(String street, String number, String postalCode) { this.street = street; this.number = number; this.postalCode = postalCode; } public Long getId() { return id; } public String getStreet() { return street; } public String getNumber() { return number; } public String getPostalCode() { return postalCode; } public List getOwners() { return owners; } @Override public boolean equals(Object o) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } Address address = (Address) o; return Objects.equals( street, address.street ) && Objects.equals( number, address.number ) && Objects.equals( postalCode, address.postalCode ); } @Override public int hashCode() { return Objects.hash( street, number, postalCode ); }}
为中间表定义一个关联实体类,定义两个@ManyToOne关联,并作为owning side。
在两个实体类中分别定义一个@OneToMany关联,都作为inverse side。关联实体类的定义如下:
@Entity(name = "PersonAddress")public static class PersonAddress implements Serializable { @Id @ManyToOne private Person person; @Id @ManyToOne private Address address; public PersonAddress() { } public PersonAddress(Person person, Address address) { this.person = person; this.address = address; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @Override public boolean equals(Object o) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } PersonAddress that = (PersonAddress) o; return Objects.equals( person, that.person ) && Objects.equals( address, that.address ); } @Override public int hashCode() { return Objects.hash( person, address ); }}注意:其中定义了两个@ManyToOne关联,并且都是作为owning side。
一个实体类定义如下:
@Entity(name = "Person")public static class Person implements Serializable { @Id @GeneratedValue private Long id; @NaturalId private String registrationNumber; @OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true) private List注意:其中定义了一个@OneToMany关联,并且作为inverse side。addresses = new ArrayList<>(); public Person() { } public Person(String registrationNumber) { this.registrationNumber = registrationNumber; } public Long getId() { return id; } public List getAddresses() { return addresses; } public void addAddress(Address address) { PersonAddress personAddress = new PersonAddress( this, address ); addresses.add( personAddress ); address.getOwners().add( personAddress ); } public void removeAddress(Address address) { PersonAddress personAddress = new PersonAddress( this, address ); address.getOwners().remove( personAddress ); addresses.remove( personAddress ); personAddress.setPerson( null ); personAddress.setAddress( null ); } @Override public boolean equals(Object o) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } Person person = (Person) o; return Objects.equals( registrationNumber, person.registrationNumber ); } @Override public int hashCode() { return Objects.hash( registrationNumber ); }}
另一个实体类定义如下:
@Entity(name = "Address")public static class Address implements Serializable { @Id @GeneratedValue private Long id; private String street; private String number; private String postalCode; @OneToMany(mappedBy = "address", cascade = CascadeType.ALL, orphanRemoval = true) private List注意:其中定义了一个@OneToMany关联,并且作为inverse side。owners = new ArrayList<>(); public Address() { } public Address(String street, String number, String postalCode) { this.street = street; this.number = number; this.postalCode = postalCode; } public Long getId() { return id; } public String getStreet() { return street; } public String getNumber() { return number; } public String getPostalCode() { return postalCode; } public List getOwners() { return owners; } @Override public boolean equals(Object o) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } Address address = (Address) o; return Objects.equals( street, address.street ) && Objects.equals( number, address.number ) && Objects.equals( postalCode, address.postalCode ); } @Override public int hashCode() { return Objects.hash( street, number, postalCode ); }}
转载地址:http://lnlai.baihongyu.com/