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>

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


  • 相关阅读:
    死锁
    面试题: JVM的四大引用
    面试题:对象怎么定位
    面试题: Spring框架的好处
    VTK 图形基本操作进阶_表面重建技术(等值面提取)
    VTK 图形基本操作进阶_表面重建技术(三角剖分)
    VTK 图形基本操作进阶_多分辨率策略(模型细化的三种方法)
    VTK 图形基本操作进阶_多分辨率策略(模型抽取的三种方法)
    VTK 图形基本操作进阶_连通区域分析
    VTK 图形基本操作进阶_网格模型的特征边 与 封闭性检测
  • 原文地址:https://www.cnblogs.com/pangblog/p/3306242.html
Copyright © 2011-2022 走看看