Hibernate的集合屬性映射簡稱集合映射
集合屬性大致有兩種:
第一種是單純的集合屬性,如像 List、Set 或數組等集合屬性;
另一種是Map結構的集合屬性,每個屬性值都有對應的Key映射。
集合映射的元素大致有如下幾種:
- List: 用於映射 List 集合屬性
- Set: 用於映射 Set 集合屬性
- Map: 用於映射 Map 集合性
- Array: 用於映射數組集合屬性
- Bag: 用於映射無序集合【包括Collection和List】
- idbag: 用於映射無序集合,但爲集合增加邏輯次序
Set 集合屬性映射與 List 非常相似,但因爲 Set 是無序的,不可重複的集合。因此 set 元素無須使用 index 元素來指定集合元素次序。
映射文件與 List 相似,區別在於使用 set 元素時,無須增加 index 列來保存集合的次序。如下映射文件:
- <span style="font-size: large;">package com.javacrazyer.domain;
- import java.util.HashSet;
- import java.util.Set;
- /**
- * 學生實體類 --> 按JavaBean的形式定義
- *
- */
- public class Student {
- private int id; //OID 對象標識符
- private String name;
- //值類型的Set集合屬性
- //值類型:沒有OID的類
- //Hiberante框架要求集合屬性必須定義成接口類型,在真正運行時Hibenrate會根據要求把實現類替換掉
- private Set<String> hobbies = new HashSet<String>();
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Set<String> getHobbies() {
- return hobbies;
- }
- public void setHobbies(Set<String> hobbies) {
- this.hobbies = hobbies;
- }
- @Override
- public String toString(){
- return "id=" + id + ",name=" + name;
- }
- }
- </span>
- <span style="font-size: large;"><?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC
- "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="com.javacrazyer.domain.Student" table="student">
- <id name="id" column="id">
- <generator class="native"/>
- </id>
- <property name="name" column="name"/>
- <!--這樣就可以生成了兩個表了,一個是上邊的student,一個是stu_hobby-->
- <set name="hobbies" table="stu_hobby" order-by="hobby_name desc">
- <!--外鍵,命名是stu_id,引用自student表的主鍵-->
- <key column="stu_id"/>
- <element column="hobby_name" type="string"/>
- </set>
- </class>
- </hibernate-mapping></span>
List是有序集合,因此持久化到數據庫時也必須增加一列來表示集合元素的次序。看持久化類,該Student.java類有個集合屬性:hobbies ,該屬性對應愛好。而集合屬性只能以接口聲明,因此代碼中,hobbies 的類型能是List ,不能是ArrayList ,但該集合屬性必須使用實現類完成初始化。【無論是種類型的集合屬性都要遵守這個規定】
在作相應映射時,list元素要求用list-index的子元素來映射有序集合的次序列。集合的屬性的值會存放有另外的表中,不可能與持久化類存儲在同一個表內。因此須以外鍵關聯,用Key元素來映射該外鍵列。
- <span style="font-size: large;"><list name="hobbies" table="stu_hob3">
- <key column="stu_id"/>
- <list-index column="posistion"/>
- <element column="hobby_name" type="string"/>
- </list></span>
3. bag 元素映射
【將student.java換成對應的List的或者Coollection的,比如:private Collection<String> hobbies = new ArrayList<String>();】
bag 元素既可以爲 List 集合屬性映射,也可以爲 Collection 集合屬性映射。不管是哪種集合屬性,使用 bag 元素都將被映射成無序集合,而集合屬性對應的表沒有
- <span style="font-size: large;"><bag name="hobbies" table="stu_hob2">
- <key column="stu_id"/>
- <element column="hobby_name" type="string"/>
- </bag></span>
Map 不公需要映射屬性值,還需要映射屬性 Key 。映射 Map 集合屬性時,同樣需要指定外鍵列,同時還必須指定 Map 的 Key 列。顯然,系統將以外鍵列和 Key 列作爲聯合主鍵。
與所有集合屬性類似,屬性聲明只能使用接口
- <span style="font-size: large;"><map name="hobbies" table="stu_hob5">
- <key column="stu_id"/>
- <map-key column="hob_id" type="string"/>
- <element type="string" column="hob_name"/>
- </map></span>
5. 集合性能的分析
對於集合屬性,通常推薦使用延遲加載策略。所謂延遲加載就是當系統需要使用集合屬性時才從數據庫裝載關聯的數據。 Hibernate對集合屬性默認採用延遲加載,在某些特殊的情況下爲 set,,list,map 等元素設置lazy="false" 屬性來取消延遲加載。
可將集合分成如下兩類:
- 有序集合:集合裏的元素 可以根據 Key 或 Index 訪問
- 無序集合:集合裏的元素中能遍歷
有序集合的屬性有增加、刪除及修改中擁有較好的性能表現。在設計較好的 Hiberate domain Object 中,集合屬性通常都會增加inverse="true" 的屬性,此時集合端不再控制關聯關係。映射 Set 集合屬性時,如果 element 元素包括 not-null="true" 屬性,則集合屬性表以關聯持久化類的外鍵和元素列作爲聯合主鍵,否則該表沒有主鍵,但 List 集合屬性的表總是以外鍵和元素次序列作爲聯合主鍵。