现在的位置: 首页 > 综合 > 正文

Hibernate征途(七)之复合主键映射和集合映射

2013年10月26日 ⁄ 综合 ⁄ 共 2833字 ⁄ 字号 评论关闭

    把这两种映射放到一起说,是因为这两种映射不像前面的复用型映射、数量和方向型映射那么分类鲜明,所以放到了这个“其他”里面。

复合主键映射

    在关系模型中,复合主键和其他的主键方式没有很大区别,但是反映到对象模型的配置上面,差别就比较大了:在对象模型中,复合主键需要一个独立的类,以下面把年和月作为复合主键为例:

    复合主键类

import java.io.Serializable;

public class FiscalYearPeriodPK implements Serializable {
	
	//核算年
	private int fiscalYear;
	
	//核算月
	private int fiscalPeriod;
	
	//省略getter和setter……
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + fiscalPeriod;
		result = prime * result + fiscalYear;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final FiscalYearPeriodPK other = (FiscalYearPeriodPK) obj;
		if (fiscalPeriod != other.fiscalPeriod)
			return false;
		if (fiscalYear != other.fiscalYear)
			return false;
		return true;
	}

}

    主键类,必须要实现序列化接口,并复写hashCode()和equals()方法。

    使用主键的类

import java.util.Date;
public class FiscalYearPeriod {
	
	private FiscalYearPeriodPK fiscalYearPeriodPK;
	
	//开始日期
	private Date beginDate;
	
	//结束日期
	private Date endDate;
	
	//状态
	private String periodSts;
	
	//省略getter和setter……

}

    映射文件

    主键类不需要独立的hbm文件,只需要为使用主键的类写映射文件即可:

<hibernate-mapping>
	<class name="com.tgb.hibernate.FiscalYearPeriod" table="t_fiscal_year_period">
		<composite-id name="fiscalYearPeriodPK">
			<key-property name="fiscalYear"/>
			<key-property name="fiscalPeriod"/>
		</composite-id>
		<property name="beginDate" type="date"/>
		<property name="endDate" type="date"/>
		<property name="periodSts"/>
	</class>
</hibernate-mapping>

    通过以上的配置,即可使用复合主键:

        

集合映射

    在集合映射中,Hibernate会为这类属性建立一张独立的表,用于存放这些数据,例如Set、List、Array、Map,以下以这些类型为例说明:

    集合类

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class CollectionMapping {

	private int id;
	
	private String name;
	
	private Set setValues = new HashSet();
	
	private List listValues = new ArrayList();
	
	private String[] arrayValues;
	
	private Map mapValues;
        
        //省略getter和setter……

}

    映射文件

<hibernate-mapping>
	<class name="com.tgb.hibernate.CollectionMapping" table="t_collection_mapping">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="setValues" table="t_set_values">
			<key column="set_id"/>
			<element type="string" column="set_value" not-null="true"/>
		</set>
		<list name="listValues" table="t_list_values">
			<key column="list_id"/>
			<list-index column="list_index"/>
			<element type="string" column="list_value"/>
		</list>
		<array name="arrayValues" table="t_array_values">
			 <key column="array_id"/>
			 <list-index column="array_index"/>
			 <element type="string" column="array_value"/>
		</array>
		<map name="mapValues" table="t_map_values">
			<key column="map_id"/>
			<map-key type="string" column="map_key"/>
			<element type="string" column="map_value"/>
		</map>
	</class>
</hibernate-mapping>

    这里在除Set外的集合都加上了list-index属性,是因为数据在这些集合中的排列是有顺序的。

    映射结果

    生成的表结构:

    

    t_array_values

    

    需要注意的是,虽然这些属性有自己的表,但它仍然是普通的属性。这表并非一张实体表,它没有自己的主键,可以算作一张伪表(一对一映射表也是),在加载时会立即加载,而不会延迟加载。

总结

    写到这里,加上前面的《Hibernate征途(四)之映射
》、《Hibernate征途(五)之继承映射和组件映射》、《Hibernate征途(六)之数量和关系映射》常见的映射都已经写完,如果问题,欢迎斧正。

抱歉!评论已关闭.