博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate中的Entity类之间的ManyToMany关联
阅读量:4179 次
发布时间:2019-05-26

本文共 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 List
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 ); }}
3.ManyToMany双向关联与两个OneToMany双向关联的等价替换

为中间表定义一个关联实体类,定义两个@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
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 ); }}
注意:其中定义了一个@OneToMany关联,并且作为inverse side。

另一个实体类定义如下:

@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
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 ); }}
注意:其中定义了一个@OneToMany关联,并且作为inverse side。

转载地址:http://lnlai.baihongyu.com/

你可能感兴趣的文章
Redis最常被问到知识点总结
查看>>
这才是微服务拆分的正确姿势,值得学习!
查看>>
MySQL中一条SQL是如何执行的?
查看>>
MySQL的索引是什么?怎么优化?
查看>>
2万字长文包教包会 JVM 内存结构
查看>>
不懂 spring 就彻底放弃 Java 吧!
查看>>
从MySQL高可用架构看高可用架构设计
查看>>
可以秒杀全场的SpringCloud微服务电商实战项目,文档贼全!
查看>>
java架构之路(多线程)synchronized详解以及锁的膨胀升级过程
查看>>
java架构之路(多线程)AQS之ReetrantLock显示锁的使用和底层源码解读
查看>>
百度现场面试:JVM+算法+Redis+数据库!(三面)
查看>>
java架构之路(多线程)JMM和volatile关键字
查看>>
创业感悟:技术兄弟为什么一直没有起来
查看>>
(转载)linux命令之十八locate 命令
查看>>
Linux发行光盘(红旗 5.0 SP2发行版,已不使用仅参考)
查看>>
linux下如何将文件打包、压缩并分割成制定大小
查看>>
CentOS6.5升级内核到3.10.28
查看>>
linux内核补丁安装和编译安装
查看>>
CentOS6.5 添加开机自启动脚本
查看>>
java.lang.IllegalArgumentException: FacesContext must not be null 错误分析及解决
查看>>