Hibernate对象关系映射----复合主键、Component、集合映射

复合主键映射

   多个字段构成主键,在现实中不太常用。一般情况下把主键相关字段拿出来,作为属性单独构成一个类,并生成geterseter方法,最重要的是单独构成的这个类必须实现序列化接口且覆盖equalshashcode方法。

   比如:FiscalYearPeriod由复合主键构成,代码:

package com.snail.hibernate;

import java.util.Date;

/**
 * 核算期间
 * @author yuanfubiao
 */
public class FiscalYearPeriod {

	private FiscalYearPeriodPK fiscalYearPeriodPK;

	//开始日期
	private Date beginDate;
	
	//结束日期
	private Date endDate;
	
	//状态
	private String periodSts;

	public FiscalYearPeriodPK getFiscalYearPeriodPK() {
		return fiscalYearPeriodPK;
	}

	public void setFiscalYearPeriodPK(FiscalYearPeriodPK fiscalYearPeriodPK) {
		this.fiscalYearPeriodPK = fiscalYearPeriodPK;
	}
	
	public Date getBeginDate() {
		return beginDate;
	}

	public void setBeginDate(Date beginDate) {
		this.beginDate = beginDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public String getPeriodSts() {
		return periodSts;
	}

	public void setPeriodSts(String periodSts) {
		this.periodSts = periodSts;
	}
}

   主键相关字段构成的单独类FiscalYearPeriodPK,代码:

package com.snail.hibernate;

import java.io.Serializable;

public class FiscalYearPeriodPK implements Serializable {
	
	private int fiscalYear;
	
	private int fiscalPeriod;

	@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;
		FiscalYearPeriodPK other = (FiscalYearPeriodPK) obj;
		if (fiscalPeriod != other.fiscalPeriod)
			return false;
		if (fiscalYear != other.fiscalYear)
			return false;
		return true;
	}

	public int getFiscalYear() {
		return fiscalYear;
	}

	public void setFiscalYear(int fiscalYear) {
		this.fiscalYear = fiscalYear;
	}

	public int getFiscalPeriod() {
		return fiscalPeriod;
	}

	public void setFiscalPeriod(int fiscalPeriod) {
		this.fiscalPeriod = fiscalPeriod;
	}
}

    FiscalYearPeriod实体类的映射文件FiscalYearPeriod.hbm.xml

<hibernate-mapping package="com.snail.hibernate">
	<class name="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>

composite-id标签里面所映射的就是FiscalYearPeriod类的两个复合主键,在对象模型中,FiscalYearPeriod持有FiscalYearPeriodPK的引用。

Component映射

   也叫组件映射。在对象模型中,为了考虑复用率,设计类一般都会从细粒度出发,尽量做到含义明确,层次分明。而关系模型的设计与对象模型恰恰相反,为了性能、便捷等因素,一般是采用粗粒度的。

   如例:

    

    UserEmployee的映射文件。

    

<hibernate-mapping package="com.snail.hibernate">
	<class name="User" table="t_user">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<component name="userContact">
			<property name="email"/>
			<property name="address"/>
			<property name="zipCode"/>
			<property name="contactTel"/>
		</component>
	</class>
</hibernate-mapping>
<hibernate-mapping package="com.snail.hibernate">
	<class name="Employee" table="t_employee">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<component name="employeeContact">
			<property name="email"/>
			<property name="address"/>
			<property name="zipCode"/>
			<property name="contactTel"/>
		</component>
	</class>
</hibernate-mapping>

   从对象模型看,ContactUserEmployee的逻辑组成部分,两个实体类分别持有它的引用,它与实体类主要差别在于没有idComponentContact)在DDD中称为值类。

   从关系模型看,最终分成了两张表,分别保存各自的数据,比对象模型粒度要粗一些。用<Component>标签完成了Component映射。

集合映射

   下面完成setlistarraymap的映射。其原理是把集合映射成一张表。

    

   实体类对象:

package com.snail.hibernate;

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

@SuppressWarnings("rawtypes")
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;

	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 getSetValues() {
		return setValues;
	}

	public void setSetValues(Set setValues) {
		this.setValues = setValues;
	}

	public List getListValues() {
		return listValues;
	}

	public void setListValues(List listValues) {
		this.listValues = listValues;
	}

	public String[] getArrayValues() {
		return arrayValues;
	}

	public void setArrayValues(String[] arrayValues) {
		this.arrayValues = arrayValues;
	}

	public Map getMapValues() {
		return mapValues;
	}

	public void setMapValues(Map mapValues) {
		this.mapValues = mapValues;
	}
}

   映射文件:

<hibernate-mapping package="com.snail.hibernate">
	<class name="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>

    <list-index>标签是防止放入表中的集合元素顺序打乱,因为Set内的元素是没有顺序的,因此不需要<list-index>标签。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值