推荐链接:
总结——》【Java】
总结——》【Mysql】
总结——》【Redis】
总结——》【Kafka】
总结——》【Spring】
总结——》【SpringBoot】
总结——》【MyBatis、MyBatis-Plus】
总结——》【Linux】
总结——》【MongoDB】
总结——》【Elasticsearch】
一、场景
以员工、地址、部门、角色四者之间的关联关系为例:
- 一个员工只能有一个地址,一个地址也只属于一个员工;
- 一个员工只能属于一个部门,但是一个部门可以包含有多个员工;
- 一个员工可以拥有多个角色,一个角色也可以属于多个员工。
表 | 实体类 | 描述 | 备注 |
---|---|---|---|
tb_employee | Employee | 员工 | 一个员工只能有一个地址 一个员工只能属于一个部门 一个员工可以拥有多个角色 |
tb_address | Address | 地址 | 一个地址只属于一个员工 |
tb_department | Department | 部门 | 一个部门可以包含有多个员工 |
tb_role | Role | 角色 | 一个角色也可以属于多个员工 |
二、关联映射
由于 @OneToOne(一对一)、@OneToMany(一对多)、@ManyToOne(多对一)、@ManyToMany(多对多) 等注解只能确定实体之间几对几的关联关系,它们并不能指定与实体相对应的数据库表中的关联字段,因此,需要与 @JoinColumn 注解来配合使用。
1、@OneToOne(一对一)
实现一:@JoinColumn
在员工表中会有一个指向地址表主键的字段address_id
// 一个员工只能有一个地址,在员工实体类中添加如下注解:
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "address_id")
private Address address;
实现二:@PrimaryKeyJoinColumn
如果员工表和地址表是以主键关联的:
- 员工表主键:employee_id
- 地址表主键:address_id
// 一个员工只能有一个地址,在员工实体类中添加如下注解:
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "address_id")
private Address address;
实现三:不使用@JoinColumn和@PrimaryKeyJoinColumn
Hibernate会自动在员工表生成关联字段,字段默认的命名规则:被控方类名_被控方主键,如:address_id
// 一个员工只能有一个地址,在员工实体类中添加如下注解:
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
// Hibernate会自动在员工表生成关联字段,字段默认的命名规则:被控方类名_被控方主键,如:address_id
private Address address;
2、@OneToMany(一对多)
一个员工只能属于一个部门,但是一个部门可以包含有多个员工,如果我们站在部门的角度来看,部门与员工之间就是一对多的关系。
实现一:@JoinColumn
// 一个部门可以包含有多个员工,在部门实体类中添加如下注解:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "department_id"