hibernate学习笔记三:表之间的关系、一对多和多对多操作

1. hibernate学习笔记三:表之间的关系、一对多和多对多操作

1.1. 一对多&&多对一之间的关系

  1. 在数据库中要将外键设置在多的一方。
  2. 在实体对象中

hibernate学习笔记三:表之间的关系、一对多和多对多操作

  1. 实体类中要分别建立具有联系的属性对象,一的建立set<>集合,多的建立属性对象并生成set和get方法。
  • 一的一方实体类
//使用set集合,表达一对多关系==================一的一方
private Set<LinkMan> linkMens = new HashSet<LinkMan>();
public Set<LinkMan> getLinkMens() {
    return linkMens;
}
public void setLinkMens(Set<LinkMan> linkMens) {
    this.linkMens = linkMens;
}
  • 多的一方实体类
//表达多对一关系
private Customer customer ;
public Customer getCustomer() {
    return customer;
}
public void setCustomer(Customer customer) {
    this.customer = customer;
}
  1. 映射表也需要对此进行修改
  • 一的一方包含三部分:name,key,class三个标签,name属性是实体对象中的多的属性对象,key值是数据库表中的外键,class属性是多的类的全限名,这里路径名在包名处已经写了
<set name="linkMens" inverse="true" cascade="delete"  >
    <key column="lkm_cust_id" ></key>
    <one-to-many class="LinkMan" />
</set>
  • 多的一方也包含三部分:name,key,class三个标签,name属性多中增加的一的实体属性,key值不变还是数据库表中的外键,即:多的一方的外键。class值是一方的全限名。
<many-to-one name="customer" column="lkm_cust_id" class="Customer"  >
</many-to-one>

1.2. 级联操作

  1. 级联操作的意义
  • 对于客户和联系人表来说,一个客户可以包含多个联系人,假如要删除某个客户,自然也要删除该客户的联系人,在没有级联操作的情况下:先删除客户,然后再逐个删除每个联系人,如果联系人有100个是不是要删除100次啊?这就产生了问题,如果在客户关系映射表上加入级联删除,就可以实现删除客户时对应的联系人也就被删除了。再例如,添加一个联系人,并指定一个新的客户,如果配置级联的cascade-update就会直接在客户表建立该客户,即使之前并没有该客户。

级联操作: cascade
save-update: 级联保存更新
delete:级联删除
all:save-update+delete
级联操作: 简化操作.目的就是为了少些两行代码.

  • 结论: 简化操作.一定要用,save-update,不建议使用delete.
  1. 级联操作的引发的问题:关系维护问题
  • 在保存时.两方都会维护外键关系.关系维护两次,冗余了. 多余的维护关系语句,显然是客户这一端在维护关系

​ inverse属性: 配置关系是否维护.
​ true: customer不维护关系
​ false(默认值): customer维护关系
​ inverse属性: 性能优化.提高关系维护的性能.
​ 原则: 无论怎么放弃,总有一方必须要维护关系.
​ 一对多关系中: 一的一方放弃.也只能一的一方放弃.多的一方不能放弃.

  • 维护关系意味着Customer可以将linkMan表的外键置为空。这样就可以单独操作Customer表了,否则Customer表被LinkMan关联着无法操作此表。不维护关系意味着操作具有级联性。
  • 不维护关系,那么要删除Customer表,就要配置级联操作,一旦删除,该客户的联系人也将被删除。

2. 多对多关系

  1. 多对多表会生成一个新的表
  2. 对每个实体类都要写一个set集合属性对象
  3. 配置映射文件需注意:下面是User.hbm.xml

name: 集合属性名
table: 配置中间表名
key
|-column:外键,别人引用"我"的外键列名
class: 我与哪个类是多对多关系
column:外键.我引用别人的外键列名

cascade级联操作:
save-update: 级联保存更新
delete:级联删除
all:级联保存更新+级联删除
结论: cascade简化代码书写.该属性使不使用无所谓. 建议要用只用save-update.
如果使用delete操作太过危险.尤其在多对多中.不建议使用.

<set name="roles" table="sys_user_role" cascade="save-update" >
    <key column="user_id" ></key>
    <many-to-many class="Role" column="role_id" ></many-to-many>
</set>
  • 中间表需要两个主键维护
  1. 只能有一方维护关联关系,至于哪个是维护的一方还需要从业务方向考虑,比如用户和角色两个表,维护的一方最好是用户表,因为还需要对用户表大量操作,而很少对角色表操作。谁的业务多,谁维护关系。
  2. cascade="save-update"可以实现将瞬时态转换为持久态,因此配置后不需要要再写session.save()这句代码了。参考文章

3. 小知识点

  1. 对代码块添加try…catch…选中代码块,Ctrl+1
  2. 可以在实体类中添加非数据库中的属性
//不与数据库中的列对应,只为了接收表单参数
private Long cust_id;
  1. 编程中,要调用下一场的方法,不用管它有没有直接写,对象也直接写,然后ctrl+1再生成全局变量。参考链接