观察
当我们只使用@ManyToOne
和@OneToMany
修饰实体的关联对象时,那么使用@ManyToOne
修饰的多的一方会自动增加一个外键来管理关联关系,同时,@OneTomany
修饰的一的一方也会自动增加一个中间表来维持关系关系。那么当级联增加时(父类中含有子类对象),会产生三种insert,分别添加两个实体和一条关联表数据,这是一的一方通过增加关联表的方式来维持关联关系。当级联增加时,我们再设置每个子类的父类属性为父类对象,那么子类的外键会被设置为父类id,这是多的一方通过设置子类外键的方式来维持关联关系。
思考
当我们使用@JoinColumn
修饰两个关联对象时,不会创建表,对于子类来说,只是指定了外键字段的名字,就算没有@JoinColumn
修饰也会创建外键。对于父类来说,使hibernate用子类的外键来维持关联关系。当我们级联增加时,inset了子类和父类,并修改了子类外键为父类id,这是一的一方通过update子类外键来维持关联关系的结果,因为结构改变了,所以一的一方改变了自己维持关联关系的方式,因为程序中没有设置子类的父类属性为父类对象,所以一的一方没有主动维持关系。当我们给一的一方修饰mappedBy时(@OneToMany(cascade={CascadeType.ALL},mappedBy)
),会使一的一方放弃维持关系,也就是他不会update子类外键,这时我们要通过在程序中设置子类对象的父类属性为父类对象来维持关系。如果父类没有放弃维持关系,同时在子类的父类属性中又设置了父类对象,那么update操作是多余的,影响性能的。
总结
有中间表的结构时,父类通过插入中间表来维持关联关系,没有时,父类通过update子类外键维持关系。子类是通过设置子类对象的父类属性为父类对象类维持关联关系。@JoinColumn
可以用来修饰一的一方,避免建立中间表,当子类的父类属性设置了父类对象时,可以用mappedBy修饰一的一方,避免多余的update属性。