Hibernate中映射集合属性
关键字: hibernate
集合属性大致有两种:第一种是单纯的集合属性,如像List、Set或数组等集合属性;另一种是Map结构的集合属性,每个属性值都有对应的Key映射。
集合映射的元素大致有如下几种:
List:用于映射List集合属性
Set:用于映射Set集合属性
Map:用于映射Map集合性
Array:用于映射数组集合属性
Bag:用于映射无序集合
idbag:用于映射无序集合,但为集合增加逻辑次序
1. List集合属性
List是有序集合,因此持久化到数据库时也必须增加一列来表示集合元素的次序。看下面的持久化类,该News类有个集合属性:schools,该属性对应学校。而集合属性只能以接口声明,因此下面代码中,schools的类型能是List,不能是ArrayList,但该集合属性必须使用实现类完成初始化。
java 代码
package cn.janwer;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class News implements Serializable {
int id;
String title;
String content;
private List schools = new ArrayList();
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List getSchools() {
return schools;
}
public void setSchools(List schools) {
this.schools = schools;
}
}
在作相应映射时,list元素要求用list-index的子元素来映射有序集合的次序列。集合的属性的值会存放有另外的表中,不可能与持久化类存储在同一个表内。因此须以外键关联,用Key元素来映射该外键列。
下面是该持久化类的映射文件:
xml 代码
<!--sp-->xml version="1.0" encoding="UTF-8"?> 主键,如下映射文件:
PUBLIC "//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.janwer.News" table="news">
<id name="id" column="pid">
<generator class="identity"/>
id>
<property name="title" length="50" column="TITLE"/>
<property name="content" length="50" column="CONTENT"/>
<!-- 映射集合属性schools,指定存放集合属性的表名 -->
<list name="schools" table="school">
<!-- 集合属性和持久化类的关联外键-->
<key column="pid" not-null="true"/>
<!-- 集合属性的次序列-->
<list-index column="list_order"/>
<!--集合元素-->
<element type="string" column="school_name"/>
list>
class>
hibernate-mapping>
2. Set集合属性
Set集合属性映射与List非常相似,但因为Set是无序的,不可重复的集合。因此set元素无须使用index元素来指定集合元素次序。
映射文件与List相似,区别在于使用set元素时,无须增加index列来保存集合的次序。如下映射文件:
<!-- 映射Set集合属性,指定集合属性存入school表-->
<set name="schools" table="school">
<!--集合属性外键列-->
<key column="pid" not-null="true"/>
<element type="string" column="school_name" not-null="true"/>
set>
3. bag元素映射
bag元素既可以为List集合属性映射,也可以为Collection集合属性映射。不管是哪种集合属性,使用bag元素都将被映射成无序集合,而集合属性对应的表没有
xml 代码
<bag name="school" table="schools">
<key column="pid" not-null="true"/>
<element type="string" column="school_name"/>
bag>
4. Map集合属性
Map不公需要映射属性值,还需要映射属性Key。映射Map集合属性时,同样需要指定外键列,同时还必须指定Map的Key列。显然,系统将以外键列和Key列作为联合主键。
与所有集合属性类似,属性声明只能使用接口,看下面的POJO类:
java 代码
private Map school = new HashMap();
public Map getSchool() {
return school;
}
public void setSchool(Map school) {
this.school = school;
}
Map集合属性使用map元素映射时,该map元素需要key和map-key两个子元素。其中key子元素用于映射外键列,而map-key子元素则用于映射Map集合的Key。映射文件如下:
xml 代码
<map name="school" table="schools">
<!-- 映射外键列 -->
<key column="pid" not-null="true"/>
<!-- 映射Map Key -->
<map-key type="string" column="indet"/>
<!-- 映射Map Value -->
<element type="float" column="score"/>
map>
注意:map-key和element元素都必须确定type属性
5. 集合性能的分析
对于集合属性,通常推荐使用延迟加载策略。所谓延迟加载就是当系统需要使用集合属性时才从数据库装载关联的数据。
Hibernate对集合属性默认采用延迟加载,在某些特殊的情况下为set,,list,map等元素设置lazy="false"属性来取消延迟加载。
可将集合分成如下两类:
有序集合:集合里的元素 可以根据Key或Index访问
无序集合:集合里的元素中能遍历
有序集合的属性有增加、删除及修改中拥有较好的性能表现。在设计较好的Hiberate domain Object中,集合属性通常都会增加inverse="true"的属性,此时集合端不再控制关联关系。
映射Set集合属性时,如果element元素包括not-null="true"属性,则集合属性表以关联持久化类的外键和元素列作为联合主键,否则该表没有主键,但List集合属性的表总是以外键和元素次序列作为联合主键。