12、复合(联合)主键映射(hibernate笔记)

一、简介

  • 复合主键映射其实应该算组件映射的一种特例,只是将相同字段抽取出来作为联合主键的字段。
  • 通常将复合主键相关的属性,单独放到一个类中:
    • 此类必须实现序列化接口
    • 覆写hashCode和equals方法,保证主键唯一

二、实例(工程hibernate_composite_mapping

相关映射:
FiscalYearPeriod.java

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

FiscalYearPeriodPK.java

package cn.itcast.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;
    }

    @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;
    }
}

FiscalYearPeriod.hbm.xml




    
        
            
             
        
        
        
        
    

说明:这里我们给出的是实际项目中有些业务需要定期核算,比如按月核算,那么某年某月的核算结果就只能有一个,于是我们将年和月作为一个联合主键。

测试:
CompositeMappingTest.java

package cn.itcast.hibernate;
import java.util.Date;
import org.hibernate.Session;
import junit.framework.TestCase;
public class CompositeMappingTest extends TestCase {

    public void testSave1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            FiscalYearPeriod fiscalYearPeriod = new FiscalYearPeriod();

            FiscalYearPeriodPK pk = new FiscalYearPeriodPK();
            pk.setFiscalYear(2008);
            pk.setFiscalPeriod(8);
            
            fiscalYearPeriod.setFiscalYearPeriodPK(pk);
            
            fiscalYearPeriod.setBeginDate(new Date());
            fiscalYearPeriod.setEndDate(new Date());
            fiscalYearPeriod.setPeriodSts("Y");
            
            session.save(fiscalYearPeriod);
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }       
    
    public void testLoad1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            
            FiscalYearPeriodPK pk = new FiscalYearPeriodPK();
            pk.setFiscalYear(2008);
            pk.setFiscalPeriod(8);
            
            FiscalYearPeriod fiscalYearPeriod = (FiscalYearPeriod)session.load(FiscalYearPeriod.class, pk);
            
            System.out.println(fiscalYearPeriod.getPeriodSts());
            
            session.getTransaction().commit();
        }catch(Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally {
            HibernateUtils.closeSession(session);
        }
    }           
}

说明:这里可以看到其存储方式和组件映射类似,只是在加载的时候我们可能麻烦点,需要分别给两个主键赋值之后去查询。

注意:现在不推荐使用此类主键,因为其和业务语义结合的太紧密,一旦业务发生变化,需要的改动很大,所以我们一般建议使用和业务语义无关的字段作为联合主键。同时在存储和加载的时候需要自己手动配置主键。

你可能感兴趣的:(12、复合(联合)主键映射(hibernate笔记))