成都心情

  语源科技BlogJava :: 首页 ::  :: 联系 :: 聚合  :: 管理 ::
  98 随笔 :: 2 文章 :: 501 评论 :: 1 Trackbacks

    在上一部分我只讲到如何通过数据库中的表生成映射文件和 POJO 。在这一部分中,我将讲解映射文件。

 

    先看看这张表:

              orm2.1.JPG

 

在现实的车辆管理系统中,绝对不会把车辆信息和拥有人信息放在一张表中。应该是“一个拥有者”拥有一或多个“车辆”。来看看分解后的表, PEOPLE 表,设置 OWNER_ID 为 主键:

orm2.2.JPG 

    AUTO_INFO 表,设置 AUTO_ID 为 主键:

 

orm2.3.JPG 

    为两表配置主、外键关系,设置 PEOPLE 表为主表:

 

          orm2.4.JPG

 

打开 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://www.blogjava.net/rosen

posted on 2005-08-12 11:30 Rosen 阅读(1240) 评论(6)  编辑  收藏 所属分类: O/R Mapping

评论

# re: 我的 O/R Mapping 之旅(二) 2006-07-26 17:50 旅行者
看过《我的 O/R Mapping 之旅》勘误及补充
还是觉得 在这里讲的主控和被控有问题(不好理解)特别是在用到级联的时候
到底people是主控方还是AutoInfo是主控方

另外主控方=拥有者吗?  回复  更多评论
  

# re: 我的 O/R Mapping 之旅(二) 2006-07-26 18:18 Rosen
people 是主控。是的,主控就是拥有。  回复  更多评论
  

# re: 我的 O/R Mapping 之旅(二) 2006-07-27 10:40 旅行者
在车辆管理系统中到底谁是主控


在车辆管理系统中,代表着一个拥有者拥有多台车辆。以 java.util.Set 类型表示。 inverse 用于标识双向关联中的被动方一端。inverse=false 的一方(主控方)负责维护关联关系;在车辆管理系统中, AutoInfo 作为主控方,应该把它设为“true”。这就好比你(被动方 one)在某个聚会上散发了许多名片,但是有可能你不清楚接收者(主动方 many)的具体背景;这个不要紧,接收者在必要的时候会和你联系就是了(主动维护关系)。

级联(cascade)在 Hibernate 映射关系中是个非常重要的概念。它指的是当主控对象调用 save-update 或 delete 方法时,是否同时对关联对象(被动方)进行 save-update 或 delete 。在这个映射文件中,当拥有者(People)被更新或者删除时,其所关联的车辆(AutoInfo)可以被修改或删除,所以应该把级联关系设置为cascade=”all”。



这两段话自相矛盾吧!
  回复  更多评论
  

# re: 我的 O/R Mapping 之旅(二) 2006-07-27 20:15 Rosen
@旅行者
其实谁作为主控,都是可以的,在本系列的勘误里面做了说明。在 HB 中,解决一个问题有很多种方式。你所提到的矛盾,实际上是我用词不够精确造成的,“拥有者”这几个字,会让人理解为主控。由于本文撰写时间比较长,在我接下来的开发中,都把拥有者作为主控方了,这样好理解。  回复  更多评论
  

# re: 我的 O/R Mapping 之旅(二) 2008-02-29 18:52 Luke Lai
Hi Rosen,
近日拜讀您的O/R Mapping之旅系列
說明的很清楚,十分感謝
但有些圖片的連結(csdn上的)似乎已經斷掉了
不知是否可以將圖片重新放上,以幫助了解?
謝謝!  回复  更多评论
  

# re: 我的 O/R Mapping 之旅(二) 2008-02-29 20:52 Rosen
@Luke Lai
谢谢关注,我看看硬盘上面还有没有。如果找不到的话,就十分抱歉了。:)  回复  更多评论