一对多单向关联映射
? ? ??可能有人會對這2篇博客的題目有點(diǎn)混淆不清,跟日常說的關(guān)系有點(diǎn)不同。我們?nèi)粘Uf的比如父子關(guān)系,夫妻關(guān)系都是說的雙向關(guān)系,而現(xiàn)在討論的則是單向關(guān)系,所以也就有了多對一和一對多的說法。
? ? ? 二者的關(guān)系其實很簡單,只是角度不同而已。比如說學(xué)生和班級的關(guān)系。如果從學(xué)生角度來看,是多對一的關(guān)系。而從班級角度來看,則是一對多的關(guān)系。說法很簡單,但是在對象和關(guān)系的建立卻是不一樣的。
? ? ? 先看一下一對多的類圖(貌似好多人的聚合關(guān)系都畫錯了):
? ? ?Hibernate對于一對多的關(guān)系的處理,是通過操作Class端,間接操作或者自動操作Student端。比如添加,我直接添加Class端的數(shù)據(jù),多個Student就會被添加自動添加進(jìn)去。也可以通過這個Class獲取到所有對應(yīng)的學(xué)生信息。跟著我來配置一下吧:
? ? ? 首先定義實體類【Class】【Student】
[java] view plain copy print?
? ? ?? hibernate.cfg.xml配置文件和hibernate.properties配置文件跟上篇博文中的一致,只是數(shù)據(jù)庫名不同而已。自行修改或者不修改都可。
? ? ? Hibernate提供了one-to-many來簡化一對多的映射關(guān)系。不用我們自己再去實現(xiàn),只需要在映射文件中進(jìn)行配置即可:
[html] view plain copy print?
? ? ? 測試類【One2ManyTest】:
[java] view plain copy print?
? ? ? 結(jié)果圖:
? ? ? 執(zhí)行測試前: ,執(zhí)行測試后:
?
? ? ? 雖然最后的結(jié)果跟多對一一樣,但是根據(jù)sql語句,就可以看出,一對多是先添加student,classid為null,等添加了class以后,再執(zhí)行update語句,把classid更新上去。這樣同時可能會暴露一個問題:如果student的classid設(shè)置了not-null="true",則會拋PropertyValueException異常。所以不太推薦使用一對多。
? ? ? 通過上面的例子,我們可以看出,其實一對多關(guān)聯(lián)映射和多對一關(guān)聯(lián)映射映射原理是一致的,都是在多的一端加入一個外鍵,指向一的一端。
? ? ? 它們的區(qū)別在于維護(hù)的關(guān)系不同:
- 多對一維護(hù)的關(guān)系是:多指向一的關(guān)系,有了此關(guān)系,在加載多的時候可以先將一加載上來
- 一對多維護(hù)的關(guān)系是:一指向多的關(guān)系,有了此關(guān)系,在加載一的時候可以先將多加載上來
? ? ? 在一的一端維護(hù)關(guān)系存在缺陷:
- 因為多的一端Student不知道Class的存在(也就是Student沒有維護(hù)與Class的關(guān)系)所以在保存Student的時候關(guān)系字段classid是為null的,如果將該關(guān)系字段設(shè)置為非空,則將無法保存數(shù)據(jù)
- 另外因為Student不維護(hù)關(guān)系,而Class維護(hù)關(guān)系,Class就會發(fā)出多余的update語句,保證Class和Student有關(guān)系,這樣加載Class的時候才可以把該Class對應(yīng)的學(xué)生加載上來
總結(jié)
- 上一篇: Spring Aop实例之AspectJ
- 下一篇: 多对一单向关联映射