多表之间的关系
- 一对一
- 一对多
- 多对多
一对一 注解说明
@OneToOne:
作用:建立一对一的关系映射
属性:
targetEntityClass:指定多的多方的类的字节码
mappedBy:指定从表实体类中引用主表对象的名称。
cascade:指定要使用的级联操作
fetch:指定是否采用延迟加载
orphanRemoval:是否使用孤儿删除
@JoinColumn
作用:用于定义主键字段和外键字段的对应关系。
属性:
name:表示的是当前类中的属性名
referencedColumnName:表示的则是 School 类中对应的属性名
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。
一对多注解说明
@OneToMany:
作用:建立一对多的关系映射
属性:
targetEntityClass:指定多的多方的类的字节码
mappedBy:指定从表实体类中引用主表对象的名称。
cascade:指定要使用的级联操作
fetch:指定是否采用延迟加载
orphanRemoval:是否使用孤儿删除
@ManyToOne
作用:建立多对一的关系
属性:
targetEntityClass:指定一的一方实体类字节码
cascade:指定要使用的级联操作
fetch:指定是否采用延迟加载
optional:关联是否可选。如果设置为false,则必须始终存在非空关系。
@JoinColumn
作用:用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。
cascade:配置级联操作
CascadeType.MERGE 级联更新
CascadeType.PERSIST 级联保存:
CascadeType.REFRESH 级联刷新:
CascadeType.REMOVE 级联删除:
CascadeType.ALL 包含所有
删除从表数据:可以随时任意删除。
删除主表数据:
有从表数据
1、在默认情况下,它会把外键字段置为null,然后删除主表数据。如果在数据库的表结构上,外键字段有非空约束,默认情况就会报错了。
2、如果配置了放弃维护关联关系的权利,则不能删除(与外键字段是否允许为null,没有关系)因为在删除时,它根本不会去更新从表的外键字段了。
3、如果还想删除,使用级联删除引用
没有从表数据引用:随便删
在实际开发中,级联删除请慎用!(在一对多的情况下)
多对多注解说明
@ManyToMany
作用:用于映射多对多关系
属性:
cascade:配置级联操作。
fetch:配置是否采用延迟加载。
targetEntity:配置目标的实体类。映射多对多的时候不用写。
@JoinTable
作用:针对中间表的配置
属性:
name:配置中间表的名称
joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段
inverseJoinColumn:中间表的外键字段关联对方表的主键字段
@JoinColumn
作用:用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。
在多对多(保存)中,如果双向都设置关系,意味着双方都维护中间表,都会往中间表插入数据,中间表的2个字段又作为联合主键,则会报错,主键重复,解决保存失败的问题:
只需要在任意一方放弃对中间表的维护权即可,推荐在被动的一方放弃,通过mappedby设置
删除操作
在多对多的删除时,双向级联删除根本不能配置
如果配了的话,如果数据之间有相互引用关系,可能会清空所有数据
fetch属性
FetchType.EAGER :立即加载 通常为多对一
FetchType.LAZY :延迟加载 通常为一对多
/**
* 学生表
**/
@Data
@Entity
@Table(name = "user_student")
public class UserStudentPo {
@Id
@GenericGenerator(name = "idGenerator", strategy = "uuid")
@GeneratedValue(generator = "idGenerator")
private String kid;
private String studentName;
private String classKid;
@ManyToOne(targetEntity = ClassAdminPo.class,optional=false)
@JoinColumn(name="classKid",referencedColumnName = "kid",insertable = false, updatable = false)
private ClassAdminPo classAdminPo;
/**
* 班级表
*/
@Data
@Entity
@Table(name = "class_admin")
public class ClassAdminPo {
@Id
@GenericGenerator(name = "idGenerator", strategy = "uuid")
@GeneratedValue(generator = "idGenerator")
private String kid;
private String className;
private String classAddr;
}
@Repository
public interface UserStudentDao extends JpaRepository<UserStudentPo, String>, JpaSpecificationExecutor<UserStudentPo> {
}
@Service
public class UserAdminServiceImpl implements UserAdminService {
@Autowired
private UserAdminDao userAdminDao;
@Override
public List<UserAdminPo> findAll(String username) {
return userAdminDao.findAll();
}
}
@RestController
@RequestMapping("student")
public class UserAdminController {
@Autowired
private UserAdminService userAdminService;
@GetMapping
public List<UserAdminPo> findAll(String username){
return userAdminService.findAll(username);
}
}