在上一部分我只讲到如何通过数据库中的表生成映射文件和
						
								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://www.blogjava.net/rosen