Hibernate关系映射——复合主键映射

来源:互联网 发布:闲来麻将源码架设教程 编辑:程序博客网 时间:2024/06/10 06:43

hibernate中复合主键的映射方式有两种。
1、基于实体类属性的复合主键
2、基于主键类的复合主键

两种映射方式的区别在于:第一种方式,主键字段和普通字段都在一个实体类中,第二种方式是单独将主键字段提取出来放到一个实体类中。

复合主键映射,主键所在的实体类,要实现Serializable接口,要覆盖hashCode()和equals()方法。

-------------------------------------------------------------

以表t_carInfo为例,t_carInfo中有字段carNo、carNoCategory、createTime三个字段,由carNo、carNoCategory构成复合主键。

1、 基于实体类属性的复合主键映射

      只有一个实体类:carInfo,包含字段carNo、carNoCategory、createTime,并且,该实体类要实现Serializable接口,重写hashCode()和equals().

      映射文件carInfo.hbm.xml:

<class name="carInfo"     table="t_carInfo>

           <composite-id>
                    <!-- key-property标签表示哪一些属性对应复合主键 -->
                    <key-property name="carNo"   type="string  />
                    <key-property name="carNoCategory"   type="string"  />
           </composite-id>
          <property name="createTime" type="Date" />

 

2. 基于逐渐类的复合主键映射

        有实体类carInfo,字段为creteTime,carInfoPK类的引用;还有一个主键类carInfoPK,字段为carNo、carNoCategory,carInfoPK这个类要实现Serializable接口,要重写hashCode()和equals()方法。

         一个映射文件carInfoPK.hbm.xml:

    <class name="carInfo"      table="t_carInfo">

          <!--和第一种方式的区只在于,composite-id中需要用name指出主键对应的对象-->
          <composite-id   name="carInfoPK"> 
                     <key-property name="carNo"/>
                     <key-property name="carNoCategory"/>
         </composite-id>
                     <property name="createTime" type="date"/>
    </class>

 

        复合主键映射,含有主键的类必须实现Serializable接口,还要覆盖equals()和hashCode()方法。这是符合主键映射同其他映射不同的地方。

        实现Serializable接口,其原因在于:当我们使用get() 、load()方法查询数据时,Hibernate中定义的get()和load()方法的定义形式如下:

     Object get( Class theClass , Serializable  id)

     Object  load(Class theClass  ,Serializable id)

      get和load方法只提供了一个传递主键的参数,由于是复合主键,至少有两个参数,所以,只能传递包含复合主键的对象,而参数类型是Serializable类型的。这样,就理解了为什么包含复合主键的类要实现Serializable接口了吧!

 Object load(Class  theClass ,Serializable  id)关于覆盖equals()和hashCode()方法,具体还是不太清楚。

这是覆盖equals和hashCode生成的代码:

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((carNo == null) ? 0 : carNo.hashCode());
  result = prime * result + ((carNoCategory == null) ? 0 : carNoCategory.hashCode());
  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 (carNo == null) {
   if (other.carNo != null)
    return false;
  } else if (!carNo.equals(other.carNo))
   return false;
  if (carNoCategory == null) {
   if (other.carNoCategory != null)
    return false;
  } else if (!carNoCategory.equals(other.carNoCategory))
   return false;
  return true;
 }

 关于为什么要重写equals()和hashCode()方法,目前还是不理解,先在这里标记个疑问,求讲解。

    

原创粉丝点击