多表之间的关系
表关系
一对一:特殊的一对多
一对多:
主表对多个从表.
在从表上新建一系列的外键,它的取值来自主表的主键
多对多:
利用中间表来关联,中间表至少有两个字段组成,这两个字段作为外键指向两张主表的主键,又组成联合主键.
实体类关系:
包含关系:可以通过实体类中的包含关系描述表关系
继承关系
开发时的步骤:
- 明确表关系
- 确定表关系(描述 外键|中间表)
- 编写实体类,在实体类中描述表关系(包含关系)
- 配置映射关系
一对多配置
第一步:编写一的一方实体类和多的一方实体类
第二步:在一的一方的实体类中配置一对多的关系
在"一的一方"创建集合泛型-- Set<多的一方实体类泛型>
两个注解:
@OneToMany(targetEntity=对方对象的字节码对象):配置一对多关系
@JoinColumn(name=“表中外键名”,referencedColumnName=“要参照的表中主键名”)
注意:在"一的一方"添加了配置,所以该实体类也具有了维护外键的作用.
例子:
第三步:在多的一方的实体类中配置多对一的关系
在"多的一方"创建"一的一方"的对象
两个注解:
@ManyToOne(一的一方的字节码对象):创建一多对一关系
@JoinColumn(name=“表中外键名”,referencedColumnName=“要参照的表中主键名”)
例子:
放弃外键维护
在持久化数据的时候,要建立实体类之间的关系,一对多或者多对一有一方建立关系即可.
在建立一对多的关系时候即"一的一方"的集合中set"多的一方"时会执行一条Update语句
在建立多对一的时候即"多的一方"中set"一的一方"时只执行两个insert语句.
那么在建立双向关系时就会导致多一条update语句,为解决这个问题就要在"一的一方"放弃外键维护.
具体操作,只需要在"一的一方"的集合上放弃外键维护,只声明关系即可:
@OneToMany(mappedBy = “多的一方中维护外键的字段”):mappedBy 属性的意思时参照对方类中字段.
例子:
删除主表数据
在有从表数据时,默认情况下它会把从表中的数据外键字段置为Null,然后删除主表数据.如果外键字段有非空约束,则删除报错.
在配置了放弃维护外键关系权力时,则不能删除,因为它不会去更新从表的外键字段.
没有从表数据时,则随便删除.
如果仍要删除,则需要使用级联操作
级联操作
简单的说就是在操作一个对象的同时操作其他关联的对象.
操作步骤:
1.需要区分操作主体
2.需要在操作的主体的实体类上添加级联属性(需要添加到多表映射关系的注解上)
3.属性名:cascode
例子:
多对多配置
配置多对多关系:
放弃中间表的维护权
在多对多关系中建立双向关系时,会重复的更新中间表的数据,造成联合主键主键冲突.
此时需要一方放弃中间表的维护权限(谁被选择谁放弃维护权).
只需要在实体类中删除中间表维护注解,将关系映射注解中属性设置为对方配置映射关系的属性名:
级联
操作哪个主体就在其类中映射关系字段的映射关系注解中添加cascade属性
对象导航查询
springDataJPA特有的查询方式,查询一个对象时,通过此对象查询所有关联的对象.
对象导航查询在查询一的一方时默认使用延迟加载的方式,在调用.get()方法时并不会执行SQL,而是在使用的时候加载
如果想要使用立即加载的方式,则需要关联对象的加载方式
注意:在使用立即加载时是使用关联查询的方式查询出所有数据
在使用对象导航查询根据"多的一方"查询"一的一方"时默认使用立即加载.