zoukankan      html  css  js  c++  java
  • 步步为营Hibernate全攻略(四)剪不断理还乱之:复合主键 && 组合映射

    一:复合主键

    复合主键即两个或多个字段联合起来作为主键,它的通常做法是将主键相关字段抽取出来放到一个单独的类中,但是这样的类是有要求的:

    1.      必须实现序列化接口

    2.      必须覆盖equals和hashCode方法

    以会计核算期中核算年和核算月做主键为例,将这两个主键相关字段放到FiscalYearPeriodPK类中,代码如下:

    package com.bjpowernode.hibernate;
    
    import java.io.Serializable;
    
    public class FiscalYearPeriodPK implements Serializable {
    		
    		//核算年
    		private int fiscalYear;
    		
    		//核算月
    		private int fiscalPeriod;
    
    		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;
    		}
    		
    		//要实现序列化接口需要覆盖hashCode和equals方法,这样才能比较
    		@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;
    		}
    }
    


    持有该类引用的FiscalYearPeriod类代码如下:

    package com.bjpowernode.hibernate;
    
    import java.util.Date;
      
    public class FiscalYearPeriod {
    	
    	private FiscalYearPeriodPK fiscalYearPeriodPK;
    	
    	//开始日期
    	private Date beginDate;
    	
    	//结束日期
    	private Date endDate;
    	
    	//状态
    	private String periodSts;
    
    	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;
    	}
    
    	public FiscalYearPeriodPK getFiscalYearPeriodPK() {
    		return fiscalYearPeriodPK;
    	}
    
    	public void setFiscalYearPeriodPK(FiscalYearPeriodPK fiscalYearPeriodPK) {
    		this.fiscalYearPeriodPK = fiscalYearPeriodPK;
    	}
    	
    	
    }
    

    来看最重要的部分,映射文件是如何进行配置的,在复合主键映射的配置中需要引入一个新的标签<composite-id>,这个标签的作用就是告诉Hibernate,生成的表使用的是复合主键,其中的<key>标签便是具体的联合主键字段,下面是映射文件内容:

    <?xml version="1.0"?>
    <!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.bjpowernode.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>

    二:组合映射

    采用组合映射的条件是由两个或多个类,他们持有多个相同的具有相同特点的成员变量(变量类型和名称一样),这时可以将这些相同的成员变量抽取出来放到另外一个类中,该类只是实体的一部分(注意这个类并不是实体类),与实体类相比它没有对象id,我们将其称之为值类。比如有User和Employee两个类,均持有  ,id,name,email,address,zipCode,contactTel属性,通过观察可知,后四个字段都属于通讯方面的信息,所以可以将这四个字段抽取出来放到类Contact中,然后让User和Employee类都持有Contact的引用即可,只要在映射文件中做好相应的配置,同样可以达到原来的映射效果。下面来看User.hbm.xml(Employee.hbm.xml与User.hbm.xml内容类似)映射文件是如何配置的:

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
    	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
          <!-- User.hbm.xml文件 -->
    	<class name="com.bjpowernode.hibernate.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>
    
        <!-- Employee.hbm.xml文件 -->
        <class name="com.bjpowernode.hibernate.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>

    通过上述配置同样可以达到每个类持有六个成员变量的效果,但是使用组合映射可以实现对象模型的细粒度划分,复用率高,含义明确,另外如果想要扩展属性的只要在抽取的类中进行扩展就可以,更加灵活。


  • 相关阅读:
    HDU4474 Yet Another Multiple Problem BFS搜索
    HDU4473 Exam 数学分析
    2013ACM多校联合(4)
    POJ1273 网络流...
    HDU4472 Count 递推
    POJ1149 PIGS 网络流
    UVA10881 Piotr's Ants 想法题
    javascript js string.Format()收集
    修改 设置 vs.net 网站 调试 设为 起始页
    【转】HTML5杂谈 概念与现行游戏 割绳子 宝石迷阵
  • 原文地址:https://www.cnblogs.com/pangblog/p/3306242.html
Copyright © 2011-2022 走看看