关于主键的维护:
一般我们会选在让多的一方维护外键,不是因为一的一方不能维护,在一对多的关系中,双方都可以进行主键的维护,并且我们把这种关系叫做双向管理,但是双方都维护主键,就会使得多出一条update语句,产生资源的浪费,原因如下:
所谓维护主键,就比如说我们通过jpa的save方法插入主表中的实体1和从表中的实体2,如果我们没有进行双方之间的关联,两条数据会被添加进数据库,但是外键部分却为null; 因此我们可以把维护主键看作是负责更新外键字段,这时如果双方都维护的话,就是出现两次update外键字段的sql
总结: 以下是OneToMany的最终方案
one:
mappedBy通过他指明,自己放弃维护外键,而参考Many端对外键的维护的实现 @OneToMany(mappedBy= "customer") // EAGER立即加载 LAZY: 延迟加载 private Set<LinkMan> linkManSet = new HashSet<>();Many
targetEntity: 指明One的一方的字节码 name: 本表中的外键的列名, 因为在多的一方维护的外键 referencedColumnName: 外键引用的主键的列名 @ManyToOne(targetEntity: = Customer.class) @JoinColumn(name = "customer_id",referencedColumnName = "id") private Customer customer; 一对多的级联cascade级联操作再One的一端进行配置
类型 作用ALL 级联所有(推荐)
PERSIST 保存
MERGE 更新
REMOVE 删除
@OneToMany(mappedBy = "customer",cascade = CascadeType.ALL,fetch = FetchType.EAGER)
级联保存: 同时存在One和Many两个对象,我们在保存One的同时级联保存Many方的对象
级联删除:
情况1: One的一方在维护主键, 这是的级联删除就会分两步走 ,首先删除外键,然后删除One的一方,同时删除One级联的去全部Many方
情况2: One的一方不再维护主键,不能级联删除
多对多配置多对多配置中,同样需要一方主动的放弃对外键维护权
双方维护着代表对方的set集合
例子: User和Role 多对多的关系
在User端,主动放弃对外键的维护权
@ManyToMany(mappedBy = "users",cascade = CascadeType.ALL) public Set<Role> roles = new HashSet<>();在Role端,维护着外键, 负责对中间表上外键的更新的操作
/** * 配置多对多 * 1. 声明关系的配置 * 2. 配置中间表(包含两个外键) * targetEntity: 对方的 实体类字节码 * */ @ManyToMany(targetEntity =User.class) @JoinTable( name = "user_role",// name 中间表名称 joinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "role_id")}, // 当前对象,在中间表中的外键名, 以及参照的本表的哪个主键名 inverseJoinColumns = {@JoinColumn(name = "sys_user_id", referencedColumnName = "user_id")} // 对方对象在中间表的外键 ) public Set<User> users = new HashSet<>(); 对象导航查询所谓对象导航查询,就是首先使用jpa为我们提供的Repository查询得到结果对象,再通过该对象,使用该对象的get方法,进而查询出它关联的对象的操作
在一对多的关系中, get的属性是 Set集合, 而在多对一的关系中,get的属性是它维护的那个One端的引用
总结:
模式 作用一查多 默认延迟加载,因为有可能一下子级联查询出成百上千的数据,但是我们却不用
多查一 默认立即查询,多查一条数据