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

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

复合主键映射

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

    复合主键类

 

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征途(七)之复合主键映射和集合映射

集合映射

    在集合映射中,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属性,是因为数据在这些集合中的排列是有顺序的。

    映射结果

 

    生成的表结构:

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

    t_array_values

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

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

总结

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

 

你可能感兴趣的:(Hibernate)