在上一部分我只讲到如何通过数据库中的表生成映射文件和 POJO。在这一部分中,我将讲解映射文件。 
  
    先看看这张表: 
                      
  
在现实的车辆管理系统中,绝对不会把车辆信息和拥有人信息放在一张表中。应该是“一个拥有者”拥有一或多个“车辆”。来看看分解后的表,PEOPLE 表,设置 OWNER_ID 为 主键: 
 
       
    AUTO_INFO 表,设置 AUTO_ID 为 主键: 
  
 
    
      为两表配置主、外键关系,设置 PEOPLE 表为主表: 
  
                  
  
打开 Eclipse,为这两张表生成映射文件。 
  
AutoInfo.hbm.xml: 
| 
 <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC  "-//Hibernate/Hibernate Mapping DTD//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > 
<hibernate-mapping package="bo">  <class name="AutoInfo" table="AUTO_INFO">   <id    column="AUTO_ID"    name="Id"    type="integer"   >    <generator class="vm" />   </id>   <property    column="LICENSE_PLATE"    length="20"    name="LicensePlate"    not-null="false"    type="string"    />   <many-to-one    class="People"    name="OwnerNo"    not-null="true"   >    <column name="OWNER_NO" />   </many-to-one>  </class> </hibernate-mapping>  |     
People.hbm.xml:  
| 
 <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC  "-//Hibernate/Hibernate Mapping DTD//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" > 
<hibernate-mapping package="bo">  <class name="People" table="PEOPLE">   <id    column="OWNER_ID"    name="Id"    type="integer"   >    <generator class="vm" />   </id>   <property    column="NAME"    length="50"    name="Name"    not-null="false"    type="string"    />   <property    column="ADDRESS"    length="1000"    name="Address"    not-null="false"    type="string"    />   <set inverse="true" name="AutoInfoSet">    <key column="OWNER_NO" />    <one-to-many class="AutoInfo" />   </set>  </class> </hibernate-mapping>  |    
 以 AutoInfo.hbm.xml 进行详细分析: 
  
DOCTYPE 定义了这个 XML 文件规范 DTD,可以通过后面的 URL 获取,或者在 Hibernate 的 CLASSPATH 中获取。
      hibernate-mapping package="bo" 定义了POJO所存在的包“bo”。   
class name="AutoInfo" table="AUTO_INFO" 定义了 POJO 的名称“AutoInfo”和数据库中的表名“AUTO_INFO”。 
  
id column="AUTO_ID" name="Id" type="integer" 定义了数据库表中的主键字段,为相应的 POJO 的每个实例包含唯一标识。column 为数据库表字段名,name 标识属性名字,type 说明在 POJO 中的类型。另外,还有一个重要标识:unsaved-value,将会在以后用到。 
  
Generator 为每个 POJO 的实例提供唯一标识。一般情况,我们使用“native”。class 表示采用由生成器接口net.sf.hibernate.id.IdentifierGenerator 实现的某个实例,其中包括: 
“assigned” 
主键由外部程序负责生成,在 save() 之前指定一个。 
  
“hilo” 
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表或字段提供高位值来源。 
  
“seqhilo” 
与hilo 类似,通过hi/lo 算法实现的主键生成机制,需要数据库中的 Sequence,适用于支持 Sequence 的数据库,如Oracle。 
  
“increment” 
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:不能在集群下使用。 
  
“identity” 
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL 中的主键生成机制。 
  
“sequence” 
采用数据库提供的 sequence 机制生成主键。如 Oralce 中的Sequence。 
  
“native” 
由 Hibernate 根据使用的数据库自行判断采用 identity、hilo、sequence 其中一种作为主键生成方式。 
  
“uuid.hex” 
由 Hibernate 基于128 位 UUID 算法 生成16 进制数值(编码后以长度32 的字符串表示)作为主键。 
  
“uuid.string” 
与uuid.hex 类似,只是生成的主键未进行编码(长度16),不能应用在 PostgreSQL 数据库中。 
  
“foreign” 
使用另外一个相关联的对象的标识符作为主键。 
      property column="LICENSE_PLATE" length="20" name="LicensePlate" not-null="false" type="string" 定义了 POJO 中的属性,分别表示数据库表中的字段、长度、POJO 属性名称以及类型、非空状态。
      many-to-one class="People" name="OwnerNo" not-null="true" column name="OWNER_NO" 定义了一个持久化对象与另一个持久化对象的关系,这种关联模型是多对一的关联。应用在车辆管理系统中,代表着多台车辆由一个拥有者拥有。分别表示关联类的名字(由反射机制得到类型)、属性名称、非空状态、字段名。 
  
分析完 AutoInfo.hbm.xml 后,再来看看 People.hbm.xml。大部分内容都已经在前面出现过,不同的地方是:
  
| 
 <set inverse="true" name="AutoInfoSet">   <key column="OWNER_NO" />   <one-to-many class="AutoInfo" /> </set>  |     
在车辆管理系统中,代表着一个拥有者拥有多台车辆。以 java.util.Set 类型表示。 inverse 用于标识双向关联中的被动方一端。inverse=false 的一方(主控方)负责维护关联关系;在车辆管理系统中, AutoInfo 作为主控方,应该把它设为“true”。这就好比你(被动方 one)在某个聚会上散发了许多名片,但是有可能你不清楚接收者(主动方 many)的具体背景;这个不要紧,接收者在必要的时候会和你联系就是了(主动维护关系)。 
  
另外在 set 节点的属性中还有一个重要标识:级联(cascade)关系,指明哪些操作(insert、update、delete)会从主控方对象级联到关联的对象。 
  
可选值: 
all: save()、saveOrUpdate()、update()、delete() 均进行级联操作。 
none: 所有情况下均不进行级联操作。 
save-update: 在执行 save()、saveOrUpdate()、update() 时进行级联操作。 
delete: 只在执行 delete() 时进行级联操作。 
  
级联(cascade)在 Hibernate 映射关系中是个非常重要的概念。它指的是当主控对象调用 save-update 或 delete 方法时,是否同时对关联对象(被动方)进行 save-update 或 delete 。在这个映射文件中,当拥有者(People)被更新或者删除时,其所关联的车辆(AutoInfo)可以被修改或删除,所以应该把级联关系设置为cascade=”all”。
 
  (请注意!引用、转贴本文应注明原作者:Rosen Jiang 以及出处:http://blog.csdn.net/rosen)  
 
  |