Hibernate中的一对一、一对多

一对一

单向一对一

首先来定义我们的实体,People。一个人只能有一个身份证,所以在IdentityCard上我们添加@OneToOne注解用于修饰该关系。

@Entity(name = "people")
public class People {
    @Id
    @GeneratedValue
    private Long id;

    @OneToOne
    private IdentityCard identityCard;
}
  • 该注解会在people的表中生成字段为identity_card_id的列,这表明这种一对一的关系是由People来维护的。
  • 在identityCard上我们还可以添加@JoinColumn(name = “identity_card_id”)注解,如果name不指定,则使用默认值。如果指定则列明为指定值。

双向一对一

除了使用@JoinColumn注解来维护People和IdentityCard之间的关系,我们还可以在定义@OneToOne时添加mappedBy。例如:

@Entity(name = "people")
public class People {
    @Id
    @GeneratedValue
    private Long id;

    @OneToOne(mappedBy = "people",)
    private IdentityCard identityCard;
}
  • mappedBy(对应XML配置中的inverse)表明这种关系是由IdentityCard来维护的,而且在IdentityCard中必须有命名为people的字段,该字段被@OneToOne注解修饰
  • 在identityCard表中会生成名为people_id的字段,但是在people表中不会有外键生成。

joinColumn和mappedBy的区别

  • 使用joinColumn表明这种关系自身来维护,mappedBy表明关系由另一方来维护。
  • 如果使用joinCoumn在一对多的时候,在保存一的那方时,会多生成几条对于多的update命令。因为在保存的时候,一的那方不知道多的那方的外键是否正确的保存。
  • 如果使用mappedBy,在保存的时候,最终只会有一条update命令用于对一的那方的更新。所以在性能上来看mappedBy是较好的。

一对多

单向一对多

当然,在实际中人和身份证不会存在一对多的关系。

@Entity(name = "people")
public class People {
    @Id
    @GeneratedValue
    private Long id;

    @OneToMany
    private List<IdentityCard> identityCards;
}
  • 如果只是在People中使用@OneToMany注解,则会生成额外一张表来维护这种关系。其中表字段为people_id和identity_card_id。
  • 如果不想生成额外的表,则可以使用@JoinColumn(name = “people_id”)。该注解会在identityCard表中新增一列外键people_id,因为一对多的关系是在多的一方那来表现出来的。你总不能在一的一方维护多的所有的id吧。

双向一对多

定义双向一对多关系,则在多的一方添加@ManyToOne注解。还记得为了避免生成额外的表,我们使用@JoinColumn注解来生成外键。但是使用@JoinColumn注解会存在我们上面提到的性能问题。所以在双向关系中我们可以在定义@OneToMany时使用mappedBy,将关系的主控方交给多的一方。

猜你喜欢

转载自blog.csdn.net/zhaoruda/article/details/80157272
今日推荐