ManyToOne
多对一,是最常见的表间关系,对应关系数据库中的外键关系。通常用于建立子实体和其父实体的关联关系
@Entity(name = "Person") public static class Person {@Id@GeneratedValueprivate Long id;//Getters and setters are omitted for brevity }@Entity(name = "Phone") public static class Phone {@Id@GeneratedValueprivate Long id;@Column(name = "`number`")private String number;@ManyToOne@JoinColumn(name = "person_id",foreignKey = @ForeignKey(name = "PERSON_ID_FK"))private Person person;//Getters and setters are omitted for brevity }
CREATE TABLE Person (id BIGINT NOT NULL ,PRIMARY KEY ( id ) )CREATE TABLE Phone (id BIGINT NOT NULL ,number VARCHAR(255) ,person_id BIGINT ,PRIMARY KEY ( id ))ALTER TABLE Phone ADD CONSTRAINT PERSON_ID_FK FOREIGN KEY (person_id) REFERENCES Person
例子:
Person person = new Person(); entityManager.persist( person );Phone phone = new Phone( "123-456-7890" ); phone.setPerson( person ); entityManager.persist( phone );entityManager.flush(); phone.setPerson( null ); INSERT INTO Person ( id ) VALUES ( 1 )INSERT INTO Phone ( number, person_id, id ) VALUES ( '123-456-7890', 1, 2 )UPDATE Phone SET number = '123-456-7890',person_id = NULL WHERE id = 2
OneToMany
一对多用于建立父实体和子实体之间的关系。如果子实体侧没有对应的ManyToOne配置,则这个OneToMany是单向的。如果子实体侧有对应的ManyToOne配置,则这个OneToMany是双向的。双向的关系,可以让开发者在两侧都能获取关联关系。
单向的一对多关系,实例:
@Entity(name = "Person") public static class Person {@Id@GeneratedValueprivate Long id;@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)private List<Phone> phones = new ArrayList<>();//Getters and setters are omitted for brevity }@Entity(name = "Phone") public static class Phone {@Id@GeneratedValueprivate Long id;@Column(name = "`number`")private String number;//Getters and setters are omitted for brevity } CREATE TABLE Person (id BIGINT NOT NULL ,PRIMARY KEY ( id ) )CREATE TABLE Person_Phone (Person_id BIGINT NOT NULL ,phones_id BIGINT NOT NULL )CREATE TABLE Phone (id BIGINT NOT NULL ,number VARCHAR(255) ,PRIMARY KEY ( id ) )ALTER TABLE Person_Phone ADD CONSTRAINT UK_9uhc5itwc9h5gcng944pcaslf UNIQUE (phones_id)ALTER TABLE Person_Phone ADD CONSTRAINT FKr38us2n8g5p9rj0b494sd3391 FOREIGN KEY (phones_id) REFERENCES PhoneALTER TABLE Person_Phone ADD CONSTRAINT FK2ex4e4p7w1cj310kg2woisjl2 FOREIGN KEY (Person_id) REFERENCES Person
Hibernate对单向的一对多关系,两个实体对应两个表,关联关系使用一个中间表来表达。单向一对多在级联操作上比较低效。
双向一对多
Hibernate处理双向一对多关系,按多对一的关系来处理,本质上还是主外键关系。双向的一对多使父子双方都能能力来获取关联关系。使操作更方便,效率等同多对一。
@Entity(name = "Person") public static class Person {@Id@GeneratedValueprivate Long id;@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true)private List<Phone> phones = new ArrayList<>();//Getters and setters are omitted for brevitypublic void addPhone(Phone phone) {phones.add( phone );phone.setPerson( this );}public void removePhone(Phone phone) {phones.remove( phone );phone.setPerson( null );} }@Entity(name = "Phone") public static class Phone {@Id@GeneratedValueprivate Long id;@NaturalId@Column(name = "`number`", unique = true)private String number;@ManyToOneprivate Person person;//Getters and setters are omitted for brevity @Overridepublic 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 );}@Overridepublic int hashCode() {return Objects.hash( number );} } CREATE TABLE Person (id BIGINT NOT NULL ,PRIMARY KEY ( id ) )CREATE TABLE Phone (id BIGINT NOT NULL ,number VARCHAR(255) ,person_id BIGINT ,PRIMARY KEY ( id ) )ALTER TABLE Phone ADD CONSTRAINT UK_l329ab0g4c1t78onljnxmbnp6 UNIQUE (number)ALTER TABLE Phone ADD CONSTRAINT FKmw13yfsjypiiq0i1osdkaeqpg FOREIGN KEY (person_id) REFERENCES Person