關聯映射就是將關聯關系映射到數據庫里,在對象模型中就是一個或多個引用。
一、Hibernate多對一關聯映射:就是在“多”的一端加外鍵,指向“一”的一端。
比如多個學生對應一個班級,多個用戶對應一個級別等等,都是多對一關系。
1、“多”端實體加入引用“一”端實體的變量及getter,setter方法。
比如說多個學生對應一個班級,在學生實體類加入:private Grade grade;
2、“多”端配置文件,student.hbm.xml里的標簽設置:<many-to-one name="grade" column="gradeId" ></many-to-one>
二、Hibernate單向的一對一主鍵關聯映射:就是讓兩個實體的主鍵一樣,就不需要加入多余的字段了。
比如一個學生對應一個身份證號,一個學生對應一條戶口信息等等,都是一對一關聯映射。
1、Person實體里要持有IdCard的引用。在Person實體里加入屬性:Private IdCard idCard;
2、Person端維護關系,所以需要重點看Person的配置文件,Person.hbm.xml通俗來講 ,就是就是Person中的Id既為主鍵又為外鍵。
所以需要修改Person中的id標簽:通俗來講是告訴Person里的id去關聯哪個實體里的id。
此處的foreign生成策略,會取得關聯對象的標識。
此處的property標簽內是關聯對象。
<id name="id">
<generator class="foreign">
<param name="property">idCard</param>
</generator>
</id>
3、在Person.hbm.xml中添加關聯關系的標簽:<one-to-one name="idCard" constrained="true"><one-to-one/>
這里的one-to-one標簽指示hibernate如何加載其關聯對象,默認根據主鍵加載也就是拿到關系字段值,根據對端的主鍵來加載關聯對象。
這里的constrained="true"表示當前主鍵Person的id主鍵,還是一個外鍵,參照了對應端的主鍵IdCard的id主鍵,會生成外鍵約束語句。
注:采用foreign映射策略在保存person對象的同時也會保存關聯的對象,也就是idCard,他們之間還有級聯關系。但是反之就不可以,也就是說,如果只保存IdCard對象,是會出錯的,不會保存Person對象,因為關系的維護端在Person端,IdCard根本就不知道Person的存在。主鍵關聯映射有弊端,不好維護。
三、Hibernate雙向一對一關聯映射:有些需求要求從一端可以查到另一端,從另一端又可以查到這一端,就需要雙向的關聯映射。
比如說,想要根據人的信息查到他的戶口信息,也想根據戶口信息查到這是哪個人的信息等。
1、修改對象模型,在IdCard.java 的實體里加入Person的引用,添加屬性:private Person person;(在Person.java實體里也有IdCard的引用哦)
2、修改IdCard.hbm.xml文件,添加one-to-one標簽。
<one-to-one name="person"/>
注1:one-to-one標簽不影響存儲,只影響加載,不會修改數據庫,也就是說不會添加字段,而many-to-one會修改數據庫,會增加一個字段。
注2:了解抓取策略:fetch="select" 可以控制查取數據的順序。
四、單向一對一唯一外鍵關聯映射:一對一主鍵關聯不好維護,用外鍵關聯對象比較好。原理:多對一的特殊情況。
比如說還是Person和IdCard的例子。
1、Person.java是實體里有IdCard的引用,即加入屬性:private IdCard idCard;IdCard.java里沒有Person引用。
2、配置文件:IdCard.hbm.xml里都是普通屬性。Person.hbm.xml的主鍵生成策略需要改變:改回:
<generator class="native"/>
使用標簽many-to-one和unique : <many-to-one name="idCard" unique="true"/> ,這樣就限制了多的一端的唯一性。
注:這里需要先保存IdCard.否則報錯。
五、雙向一對一唯一外鍵關聯:如果有需求要求的情況下,也可以建立雙向的外鍵關聯。
1、在Person和IdCard里添加對應端的引用,即添加相應屬性。
2、person.hbm.xml和例子(四)中一樣,修改IdCard.hbm.xml文件,添加one-to-one標簽:<one-to-one name="person" property-ref="idCard"></one-to-one>.
注:必須指定one-to-one標簽中的property-ref屬性為關系字段的名稱。
六、Hibernate單向一對多關聯映射:讓一的一端維護關系,和多對一的映射原理是一樣的,都是在多的一端加入一個外鍵指向一的一端;
區別在於維護的關系不同:
- 多對一維護的關系:多指向一的關系,如果維護了多指向一的關系,那么加載多的一端的時候會把一的一端加載上來;
- 一對多維護的關系:一指向多的關系,如果維護了一指向多的關系,那么加載一的一端的時候會把多的一端加載上來。
比如說一個班里有多名學生。
1、Classes.java 和 Student.java里各有兩個普通屬性id和name。在Classes里加入新屬性:private Set students;
2、映射文件的修改:Classes.hbm.xml里除了普通屬性,加入集合映射:
<set name="students">
<key column="classesid"></key>
<one-to-many class="com.juyahong.hibernate.Student"/>
</set>
注1:“一”的一端維護關系。
注2:session.save(student),session.save(classes),保存student和classes對象。可以成功保存數據,但是需要發出多余的update語句來維持關系。
下篇博客繼續分析。