注册 | 登录
收藏 | 帮助
热门文章
编辑推荐
相关文章  
DNS 系统设定例--13.[Fwd] NCTU 
IBM Aix上Qmail的建立
如何在HP-UX 10.20系统中正确地配
彻底搞清楚library cache lock的
彻底搞清楚library cache lock的
彻底搞清楚library cache lock的
IBM DB2 日常维护汇总(一)
IBM DB2 日常维护汇总(二)
IBM DB2 日常维护汇总(三)
IBM DB2 日常维护汇总(四)
您现在的位置: 顶尖设计 >> IT学院 >> 编程开发 >> Java >> 文章正文
在Hibernate中实现复杂的数据映射
作者:佚名  来源:不详  点击:  更新:2006-12-19
简介:

在第一篇文章中,我们对一个表进行了简单的封装。在这篇文章中,我们讨论更加复杂的情况。

在这个例子中,将考虑到表之间的一对一、一对多、多对多的情况。如图1所示。

 

图1 实体之间的映射关系
图1 实体之间的映射关系

 

在上面的数据模型图中,Student是所有表的核心,它和Classes表是一对多的关系,和Course表是多对多的关系(通过Student_Course_Link表来链接),和Address表是一对一的关系。

通过分析,我们可以把上面的数据模型转换成如下的Java持久对象,如图2所示。

 

图2 持久对象之间的关系
图2 持久对象之间的关系

 

可以看出,数据模型图和Java持久对象的类图有非常大的相似性,但是不完全相同。比如Classes表和Student表是一对多的关系;在类图中,两者仍然是一对多的关系,但是在Classes类中添加了一个student属性,属性的类型是java.util.Set,它表示Classes对象中包含的所有Student对象。

创建Hibernate持久对象

已经对数据模型经过了分析,现在就可以创建持久对象了。持久对象之间的关系由图2所示的类图指定。

我们首先来看Student类,它是这个关系映射的核心,代码如例程1所示。

例程1 Student持久对象(Student.java)

 package com.hellking.study.hibernate;  
import java.util.Set; /**  *在hibernate中代表了Students表的类。  */ 
public class Student  {    /**属性,和students表中的字段对应**/    
private String id;    
private String name;    /**和其它类之间的映射关系**/    
private Set courses;    
private Classes classes;    
private Address address;         /**属性的访问方法,必须是公共的方法**/    
 public void setId(String string) {   id = string;  }  
  public String getId() {   return id;  }    
public void setName(String name)  {   this.name=name;  }  
public String getName()  {   return this.name;  }    /**操作和其它对象之间的关系**/  
public void setCourses(Set co)  {   this.courses=co;  }
  public Set getCourses()  {   return this.courses;  } 
 public void setAddress(Address ad)  {   this.address=address;  }  
public Address getAddress()  {   return this.address;  } 
 public void setClasses(Classes c)  {   this.classes=c;  } 
 public Classes getClasses()  {   return this.classes;  }   } 

在Student类中,由于Students表和Classes的表是多对一的关系,故它包含了一个类型为Classes的classes属性,它的实际意义是一个学生可以有一个班级;Students表和Address的表是一对一的关系,同样也包含了一个类型为Address的address属性,它的实际意义是一个学生有一个地址;Students表和Course是多对多的关系,故它包含了一个类型为java.util.Set的course属性,它的实际意义是一个学生可以学习多门课程,同样,某个课程可以由多个学生来选修。

Classes对象和Student对象是一对多的关系。Classes对象包含一个类型为java.util.Set的students属性,它的代码如例程2所示。

例程2 Classes持久对象(Classes.java)

 package com.hellking.study.hibernate; 
 import java.util.Set; /**  *在hibernate中代表了Classes表的类。  */ 
public class Classes  {    /**属性,和classes表的字段一致**/   
 private String id;     
 private String name;    /**和其它类之间的映射关系**/    
private Set students;        /**属性的访问方法,必须是公共的方法**/   
 public void setId(String string) {   id = string;  }   
 public String getId() {   return id;  }   
 public void setName(String name)  {   this.name=name;  } 
 public String getName()  {   return this.name;  }    /**操作和其它对象之间的关系**/ 
 public void setStudents(Set stud)  {   this.students=stud;  } 
 public Set getStudents()  {   return this.students;  } } 

Course持久对象在前一篇文章已经介绍,在这里就不再列举。Address持久对象比较简单,除了表字段定义的属性外,没有引入其它的属性,请参考本文的代码。

描述对象之间的关系

现在我们已经编写好了持久对象,下面的任务就是描述它们之间的关系。首先我们看Student持久对象的描述,如例程3所示。

例程3 Student持久对象的描述(Student.hbm.xml)

 <?xml version="1.0"?>  <!DOCTYPE hibernate-mapping PUBLIC    
 "-//Hibernate/Hibernate Mapping DTD 2.0//EN"     
 "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">  
<hibernate-mapping>    
 <class name="com.hellking.study.hibernate.Student" table="Students" dynamic-update="false" >  
 <!-- 描述ID字段--> 
 <id  name="id"  column="StudentId" type="string"  unsaved-value="any"  > 
<generator class="assigned"/> </id> 
<!-- 属性-->          
<property   name="name"  type="string"             
update="true"             
insert="true"             
column="Name" /> <!-- 描述Student和Course多对多的关系-->   
 <set   name="courses"  table="Student_Course_Link"  
lazy="false" inverse="false"  cascade="all"  sort="unsorted"         > 
<key   column="StudentId"  />                
<many-to-many class="com.hellking.study.hibernate.Course"  
column="CourseId"                   
outer-join="auto" />         
</set> <!-- 描述Student和Classes之间多对一的关系-->          
 <many-to-one  name="classes"  class="com.hellking.study.hibernate.Classes"             
cascade="none"             
outer-join="auto"             
update="true"             
insert="true"             
column="ClassesId"         
/>          
<!-- 描述Student和Address之间一对一的关系-->          
<one-to-one            
 name="address"            
 class="com.hellking.study.hibernate.Address"            
 cascade="none"             
outer-join="auto"             
constrained="false"         />            
</class> </hibernate-mapping> 

在Student.hbm.xml描述符中,共描述了三种关系。第一种是Student和Address之间一对一的关系,它是最简单的关系,使用:

 <one-to-one name="" class=""> 

来描述,这里的name表示的是Student对象中名称为address的属性;class表示的是address属性的类型:com.hellking.study.hibernate.Address。

接下来看Student和Classes之间多对一的关系,使用:

 <many-to-one   name="classes" class="com.hellking.study.hibernate.Classes" column="ClassesId" …   /> 

来描述。同样,name表示的是Student对象中名称为classes的属性;class表示的是classes属性的类型,column表示Student表引用Classes表使用的外部键名称。对应的,在Classes类中也引用了Student类,它使用了以下的描述符来描述这个关系:

<set  name="students" table="Students" lazy="false" 
inverse="false"             
cascade="all"             
sort="unsorted"         
>               
<key  column="ClassesId" />                
<one-to-many  class="com.hellking.study.hibernate.Student" /></set>         

在描述Student和Course之间多对多关系时,使用了以下的方法:

<set  name="courses" table="Student_Course_Link"             
lazy="false"             
inverse="false"             
cascade="all"             
sort="unsorted"         >               
<key column="StudentId"  />
<many-to-many  class="com.hellking.study.hibernate.Course"                   
column="CourseId"                   
outer-join="auto" />
</set>         

在映射多对多关系时,需要另外使用一个链接表,这个表的名字由table属性指定,链接表包含了两个字段:CourseId和StudentId。以下的描述:

 <key column="StudentId"> 

指定了Student对象在Student_Course_Link链接表中的外部键。对应的,在Course持久对象使用了以下的描述符来描述这个关系:

<set  name="students" table="Student_Course_Link" lazy="false" inverse="false" 
cascade="all"             
sort="unsorted" >               
<key column="CourseId" />                
<many-to-many  class="com.hellking.study.hibernate.Student"  
column="StudentId"                   
outer-join="auto" />         
</set>         

由于其它持久对象的描述基本一样,在这里就不一一列举了,请参考本文的源代码。最后别忘了在hibernate.cfg.xml里增加这几个对象的描述。

<!-- Mapping files -->        
 <mapping resource="Address.hbm.xml"/>         
<mapping resource="Student.hbm.xml"/>        
 <mapping resource="Classes.hbm.xml"/>        
 <mapping resource="Course.hbm.xml"/         

使用映射关系

下面我们开发一个简单的实例来测试这个映射。持久对象使用最频繁的操作是增加数据、查询数据、删除数据、更新数据。对于更新数据的操作的情况,多个表的操作和单个表没有两样,在这里不举例了。

添加数据到数据库

我们在这里测试前三种操作,首先来看添加数据到数据库的情况,如例程4所示。

例程4 测试持久对象之间的映射关系之添加数据(MapTestBean.java部分代码)

/**   *在数据库中添加数据   */   
public void addData(String studentId,String classesId,String coursesId)  
throws HibernateException {         
try {  /***以下的代码添加了一个Student,同时为Student指定了 *Address、Courses和Classses。   */       
beginTransaction();    
//创建一个Student对象 。            

[1] [2] 下一页






  • 上一篇文章:
  • 下一篇文章:
  • 分享此文:该页面添加到 Mister Wong 添加到雅虎Yahoo!收藏 Add to:Del.icio.us Post to Furl Digg this 添加到Google书签 reddit spurl blogmarks 365Key 评论  收藏  分享  打印
     我来说两句
    姓名:       验证码:   
    主页: 
    评分: 1分 2分 3分 4分 5分
    本频道近期热评文章:
      关于我们 | 联系我们 | 站点地图 | 广告投放 | 友情链接 | 在线留言 | 版权申明
    版权所有 © 2004-2007 顶尖设计(bobd.cn)
    未经授权禁止转载,摘编,复制本站内容或建立镜像. 沪ICP备07504942号 
    网络110
    报警服务