hibernate的OneToMany和ManyToOne映射
1、前言
在数据库中,不管一对多或者多对一都统称为:一对多。@OneToMany和@ManyToOne指定了一对多的关系。
2、@OneToMany使用外键映射的单向一对多关联
单向关联
entity:Member
@Entity
@Setter
@Getter
@Table(name = "jei_member")
public class Member implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
@ApiModelProperty(value = "id")
private Long id;
@Column(name = "name")
@ApiModelProperty(value = "姓名")
private String name;
@Column(name = "gender")
@ApiModelProperty(value = "性别")
private Integer gender;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", referencedColumnName = "id", insertable = false, updatable = false)
private Set<Order> orders;
public Set<OrderDto> getOrderDtos() {
if (orders == null) {
return null;
}
return orders.stream().map(x -> new OrderDto(x.getId(), x.getProductName(), x.getProductNum(), x.getMemberId())).collect(Collectors.toSet());
}
}
注意:
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", referencedColumnName = "id", insertable = false, updatable = false)
这里@JoinColumn()中name="member_id"指子表(MANY)中的字段, referencedColumnName = "id"指当前表(ONE)中的字段。
3、@ManyToOne使用外键映射的单向一对多关联
单向关联
entity:Order
@Entity
@Setter
@Getter
@Table(name = "jei_order")
public class Order implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
@ApiModelProperty(value = "id")
private Long id;
@Column(name = "product_name")
@ApiModelProperty(value = "商品名称")
private String productName;
@Column(name = "product_num")
@ApiModelProperty(value = "数量")
private Integer productNum;
@Column(name = "member_id")
@ApiModelProperty(value = "会员id")
private Long memberId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", referencedColumnName = "id", insertable = false, updatable = false)
private Member member;
}
注意:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", referencedColumnName = "id", insertable = false, updatable = false)
这里的name=“member_id”, 指的当前表(MANY)的字段,referencedColumnName = "id"只能是主表(ONE)的主键id。
4、@OneToMany和@ManyToOne使用外键映射的双向一对多关联
entity:Menber
@Entity
@Setter
@Getter
@Table(name = "jei_member")
public class Member implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
@ApiModelProperty(value = "id")
private Long id;
@Column(name = "name")
@ApiModelProperty(value = "姓名")
private String name;
@Column(name = "gender")
@ApiModelProperty(value = "性别")
private Integer gender;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "member")
private Set<Order> orders;
public Set<OrderDto> getOrderDtos() {
if (orders == null) {
return null;
}
return orders.stream().map(x -> new OrderDto(x.getId(), x.getProductName(), x.getProductNum(), x.getMemberId(), x.getMember().getName(), x.getMember().getGender()))
.collect(Collectors.toSet());
}
}
注意:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "member")
这里不需要@JoinColumn进行声明关联,需要用mappedBy 来确定关系由谁来维护。mappedBy="member"说明在两个关联的实体Bean中,member这一端是关系的拥有者。
entity:Order
@Entity
@Setter
@Getter
@Table(name = "jei_order")
public class Order implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
@ApiModelProperty(value = "id")
private Long id;
@Column(name = "product_name")
@ApiModelProperty(value = "商品名称")
private String productName;
@Column(name = "product_num")
@ApiModelProperty(value = "数量")
private Integer productNum;
@Column(name = "member_id")
@ApiModelProperty(value = "会员id")
private Long memberId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", referencedColumnName = "id",insertable = false,updatable = false)
private Member member;
}
注意:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", referencedColumnName = "id", insertable = false, updatable = false)
这里的name=“member_id”, 指的当前表(MANY)的字段,referencedColumnName = "id"只能是主表(ONE)的主键id。
总结:
1、@JoinColumn(name = "many_id", referencedColumnName = "one_id", insertable = false, updatable = false)
2、在一对多的情况下,一定要注意死循环的问题,实体类中使用@Setter、@Getter。@data双向关联的情况下,会出现栈溢出。