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 集合属性的表总是以外键和元素次序列作为联合主键。