组件映射

联合主键(表中的主键由两个或两个以上字段组成)。在Hibernate中联合主键的形成有两种可能:一种是由多对多映射形成的,多对多映射会形成第三张表,一般来说第三张表的主键是由其他两张表的主键构成的(比如学生表,课程表,选课表)。第二种情况就是很常见的情况,即只有一张表,表的主键是由本身的两个字段或以上构成的。

假设我们有两个类,SalDate类表示联合主键(year、month),Total类(private int salTotal;private SalDate sd;)建完这两个类之后我们开始写Total.hbm.xml的配置文件:

 

  1. <hibernate-mapping package="com.fendou.hibernate">  
  2.     <class name="Total" table="t_salTotal">  
  3.         <composite-id name="sd">  
  4.             <key-property name="year"/>  
  5.             <key-property name="month"/>  
  6.         </composite-id>  
  7.         <property name="salTotal" length="50" column="sTotal"/>  
  8.           
  9.     </class>  
  10. </hibernate-mapping>  

 

 

下面我们运行下,出现下面结果:

create table t_salTotal (year integer not null, month integer not null, sTotal integer, primary key (year, month))

没有问题。下面我们插入几条数据测试下:

 

  1. session = HibernateUtils.getSession();  
  2.             //开启事务  
  3.             tr = session.beginTransaction();  
  4.             SalDate d1 = new SalDate();  
  5.             d1.setMonth(12);  
  6.             d1.setYear(2010);  
  7.               
  8.             SalDate d2 = new SalDate();  
  9.             d2.setMonth(12);  
  10.             d2.setYear(2010);  
  11.               
  12.             Total t1 = new Total();  
  13.             t1.setSalTotal(10000);  
  14.             t1.setSd(d1);  
  15.               
  16.             Total t2 = new Total();  
  17.             t2.setSalTotal(30000);  
  18.             t2.setSd(d2);  
  19.             session.save(t1);  
  20.             session.save(t2);  
  21.             tr.commit();  

 

 

运行下:结果杯具了:20:55:57,078  WARN RootClass:215 - composite-id class does not override hashCode(): com.fendou.hibernate.SalDate

这句话告诉我们联合主键composite-id标签要求SalDate重写equals和hashCode方法.同时我们还需要实现Serializable接口。为什么要重写这两个方法以及实现Serializable

重写equals和hashCode方法是为了唯一确定一条记录以便用来作为持久化对象的标识。在Hibernate中要求一个标识必须是持久化的,所以必须将salDate实现Serializable接口。

帮助文档是这样说的:Unfortunately, this approach to composite identifiers means that a persistent object is its own identifier. There is no convenient "handle" other than the object itself. You must instantiate an instance of the persistent class itself and populate its identifier properties before you canload() the persistent state associated with a composite key.

上面那段英文中的后半部分是教我们怎么进行查询,在查询的时候我们先持久化一个主键对象标识然后查询:

 

  1. SalDate sd = new SalDate();  
  2. sd.setMonth(3);  
  3. sd.setYear(2011);         
  4. Total t = (Total)session.load(Total.class, sd);  

 

 

如果你对此不大了解的话,你可以查看Load的源代码,源代码中Load函数的原型是:

 

 

 

 

 

public Object load(Class entityClass, Serializable id) throws HibernateException {

return load( entityClass.getName(), id );

}

而我们查找的主键sd刚好是一个序列化对象,所以能正确查找。

 

 

 

 

 

 

组件映射:组件映射相对比较简单,所谓的组件就是一个被包含的对象。比如我们可以将通讯方式设置为一个组件,这个组件里面包含(QQ,MSN,Email,住址),而其他的对象皆可以使用这个组件,比如Teacher对象、Student对象。

这个实在没什么好说的,直接贴代码吧:

组件对象代码如下:

 

  1. package com.fendou.hibernate;  
  2. public class Component {  
  3.     private String name;  
  4.     private String tel;  
  5.     private String address;  
  6.     private String email;  
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.     public void setName(String name) {  
  11.         this.name = name;  
  12.     }  
  13.     public String getTel() {  
  14.         return tel;  
  15.     }  
  16.     public void setTel(String tel) {  
  17.         this.tel = tel;  
  18.     }  
  19.       
  20.     public String getAddress() {  
  21.         return address;  
  22.     }  
  23.     public void setAddress(String address) {  
  24.         this.address = address;  
  25.     }  
  26.     public String getEmail() {  
  27.         return email;  
  28.     }  
  29.     public void setEmail(String email) {  
  30.         this.email = email;  
  31.     }  
  32.       
  33.       
  34.       
  35. }  

 

 

使用组件的Teacher对象如下:

 

  1. package com.fendou.hibernate;  
  2. public class Teacher {  
  3.     private int id;  
  4.     private int sal;  
  5.     public Component getComp() {  
  6.         return comp;  
  7.     }  
  8.     public void setComp(Component comp) {  
  9.         this.comp = comp;  
  10.     }  
  11.     private Component comp;  
  12.     public int getId() {  
  13.         return id;  
  14.     }  
  15.     public void setId(int id) {  
  16.         this.id = id;  
  17.     }  
  18.   
  19.     public int getSal() {  
  20.         return sal;  
  21.     }  
  22.     public void setSal(int sal) {  
  23.         this.sal = sal;  
  24.     }  
  25.       
  26. }  

 

 

配置文件如下:

 

  1. <hibernate-mapping package="com.fendou.hibernate">  
  2.     <class name="Teacher" table="t_teacher">  
  3.         <id name="id" column="tid" length="2">  
  4.             <generator class="native"></generator>  
  5.         </id>  
  6.         <property name="sal" />  
  7.         <component name="comp">  
  8.             <property name="name"/>  
  9.             <property name="tel"/>  
  10.             <property name="email"/>  
  11.             <property name="address"/>  
  12.         </component>  
  13.     </class>  
  14. </hibernate-mapping>

 

posted @ 2016-09-05 14:47  方圆i  阅读(242)  评论(0编辑  收藏  举报