【04】框架学习—Hibernate中处理一对多关系与多对多关系
1.一对多关系处理
示例:客户(Customer)与联系人(Linkman)的关系(一个客户有多个联系人)
1.JavaBean的编写
前提:数据库中客户表的主键是联系人表的外键。
JavaBean中: “一”方需要有“多”方的Bean集合,“多”方需要有“一”方的引用。
示例如下:
2.映射文件的编写
Linkman.hbm.xml中:
Customer.hbm.xml中:
3.双向关联保存数据
缺点很明显,麻烦,每次保存数据,都需要设置双方。
4.级联保存数据
如果想完成只保存一方的数据,并且把相关联的数据都保存到数据库中,那么需要配置级联。
使用cascade=”save-update”。
级联是有方向性的,可以是一方级联多方,也可以是多方级联一方。(下面演示一方级联多方,即客户级联联系人)
示例如下:
先在Customer映射文件中的set标签加上cascade属性:
然后代码如下:
5.级联删除
删除时,如果是普通删除一方,会先把多方的外键置空。
级联删除,在映射文件加上cascade=”delete”。
6.级联(cascade)的取值
none:不试用级联。
save-update:级联保存或更新。
delete:级联删除。
delete-orphan:孤儿删除(只能用在一对多关系中)。
all:包含save-update、delete的情况。
all-delete-orphan:包含save-update、delete、delete-orphan的情况。
关于孤儿删除:
在一对多中,“一”方被认为是父方,“多”方是子方。孤儿删除是解除父子关系时将子方的记录删除。
配置:在父方的映射文件中加入 :
7.让某一方放弃外键的维护,为多对多做准备
前提:现一客户与其两个联系人、新客户没联系人,通过Java程序将客户的第一个联系人“转给”新客户。
代码如下:
Hibernate执行的sql语句:
可以看到,双方都维护外键,造成重复。让“一”方放弃对外键的维护可避免这种情况的发生(这里思考为什么要“一”方放弃)。
映射文件中添加inverse标签:
8.cascade和inverse的区别
1.cascade是级联操作(保存、修改和删除数据)。
2.inverse是放弃对外键的维护。
例子:
2.多对多关系处理
1.什么是多对多?
这里举个例子,一个人(User)通常有多种身份(Role),而一种身份又可对应多个人。例如:公司里面小王是经理,到社会小王是社会大哥。而公司的经理不只有一个,社会大哥也还有别人,这就是多对多。
2.多对多配置
JavaBean中都有存储另外一方的集合。
映射文件中是many-to-many,并规定好中间表。
注意:多对多时必须有一方放弃对外键的维护!
补充:
多对多时一般不用级联删除,因为会把另一方表记录删除,导致其它与它关联的记录也被级联删除。
Hibernate解除多对多的关系时通过对集合的操作