hibernate.hbm.xml详解

在Hibernate中,各表的映射文件….hbm.xml可以通过工具生成,例如在使用MyEclipse开发时,它提供了自动生成映射文件的工具。配置文件的基本结构如下:

 1 <?xml version="1.0" encoding=‘UTF-8‘?>  
 2   
 3 <!DOCTYPE hibernate-mapping PUBLIC   
 4      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
 5      "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
 6 <hibernate-mapping package="包名">  
 7    <classname="类名" table="表名">  
 8       <id name="主键在java类中的字段名" column="对应表中字段" type="类型">  
 9           <generatorclass="主键生成策略"/>  
10       </id>  
11   
12           ……   
13     </class>  
14 </hibernate-mapping> 

1. 主键(id)
Hibernate的主键生成策略有如下几种:
1) assigned
主键由外部程序负责生成,在 save() 之前指定。
2) hilo
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表或字段提供高位值来源。
3) seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,需要数据库中的 Sequence,适用于支持 Sequence 的数据库,如Oracle。
4) increment
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:不能在集群下使用。
5) identity
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL 中的主键生成机制。
6) sequence
采用数据库提供的 sequence 机制生成主键。如 Oralce 中的Sequence。
7) native
由 Hibernate 根据使用的数据库自行判断采用 identity、hilo、sequence 其中一种作为主键生成方式。
8) uuid.hex
由 Hibernate 基于128 位 UUID 算法 生成16 进制数值(编码后以长度32 的字符串表示)作为主键。
9) uuid.string
与uuid.hex 类似,只是生成的主键未进行编码(长度16),不能应用在 PostgreSQL 数据中。
10) foreign
使用另外一个相关联的对象的标识符作为主键。
主键配置举例如下:

1 <id name="id" column="id" type="java.lang.Integer">  
2   <generatorclass="native"/>  
3 </id>

2. 普通属性(property)

       开发人员可以打开网址:http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd 来查看hibernate3.0的dtd信息,可看到property的定义如下:

 1 <!-- Property of an entity class or component, component-element, composite-id, etc. 
 2 JavaBeans style properties are mapped to table columns. -->
 3 
 4 <!ELEMENT property (meta*,(column|formula)*,type?)>
 5     <!ATTLIST property name CDATA #REQUIRED>
 6     <!ATTLIST property node CDATA #IMPLIED>
 7     <!ATTLIST property access CDATA #IMPLIED>
 8     <!ATTLIST property type CDATA #IMPLIED>
 9     <!ATTLIST property column CDATA #IMPLIED>
10     <!ATTLIST property length CDATA #IMPLIED>
11     <!ATTLIST property precision CDATA #IMPLIED>
12     <!ATTLIST property scale CDATA #IMPLIED>
13     <!ATTLIST property not-null (true|false) #IMPLIED>
14     <!ATTLIST property unique (true|false) "false">
15     <!ATTLIST property unique-key CDATA #IMPLIED>
16     <!ATTLIST property index CDATA #IMPLIED>                <!-- include the columns spanned by this property in an index -->
17     <!ATTLIST property update (true|false) #IMPLIED>
18     <!ATTLIST property insert (true|false) #IMPLIED>
19     <!ATTLIST property optimistic-lock (true|false) "true">    <!-- only supported for properties of a class (not component) -->
20     <!ATTLIST property formula CDATA #IMPLIED>
21     <!ATTLIST property lazy (true|false) "false">
22     <!ATTLIST property generated (never|insert|always) "never">

它的各属性中比较常用的有:

name(对应的java类的属性名称)

column(对应的表中的字段)

type(属性的类型,比如java的类型java.lang.String, java.util.Calendar等,或者hibernate的类型integer, long, short, float, double, character, byte, boolean, yes_no, true_false, date, calendar等,hibernate的type即代表java类型到数据库字段类型的映射。)

not-null(设置该属性是否为空,为true时表示非空,默认为false)和length(字段的长度限制)

Eg1. <property name="accessname" column="accessName" type="java.lang.String" not-null="true"/>

Eg2. <property name="state" column="state" type="java.lang.Byte" not-null="true"/>

Eg3. <property name="description" column="description" type="java.lang.String"/>

3. 一对多(多对一)关系

"一对多"是最普遍的映射关系,简单来讲就如消费者与订单的关系。

一对多:从消费者角的度来说一个消费者可以有多个订单,即为一对多。

多对一:从订单的角度来说多个订单可以对应一个消费者,即为多对一。

一对多关系在hbm文件中的配置信息(双向一对多):

消费者(一方):

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 3     <hibernate-mapping>
 4         <class name="com.suxiaolei.hibernate.pojos.Customer" table="customer">
 5             <!-- 主键设置 -->
 6             <id name="id" type="string">
 7                 <column name="id"></column>
 8                 <generator class="uuid"></generator>
 9             </id>
10             <!-- 属性设置 -->
11             <property name="username" column="username" type="string"></property>
12             <property name="balance" column="balance" type="integer"></property>
13             
14             <set name="orders" inverse="true" cascade="all">
15                 <key column="customer_id" ></key>
16                 <one-to-many class="com.suxiaolei.hibernate.pojos.Order"/>
17             </set>
18         </class>
19     </hibernate-mapping>

订单(多方):

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 3     <hibernate-mapping>
 4         <class name="com.suxiaolei.hibernate.pojos.Order" table="orders">
 5             <id name="id" type="string">
 6                 <column name="id"></column>
 7                 <generator class="uuid"></generator>
 8             </id>
 9             
10             <property name="orderNumber" column="orderNumber" type="string"></property>
11             <property name="cost" column="cost" type="integer"></property>
12             
13             <many-to-one name="customer" class="com.suxiaolei.hibernate.pojos.Customer" 
14                          column="customer_id" cascade="save-update">
15             </many-to-one>        
16         </class>
17     </hibernate-mapping>

"一对多"关联关系,Customer方对应多个Order方,所以Customer包含一个集合用于存储多个Order,Order包含一个Customer用于储存关联自己的Customer。

一对多关联关系有一种特例:自身一对多关联。例如:

自身一对多关联自身的hbm文件设置:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 3     
 4     <hibernate-mapping>
 5         <class name="com.suxiaolei.hibernate.pojos.Category" table="category">
 6             <id name="id" type="string">
 7                 <column name="id"></column>
 8                 <generator class="uuid"></generator>
 9             </id>
10             
11             <property name="name" column="name" type="string"></property>
12             
13             <set name="chidrenCategories" cascade="all" inverse="true">
14                 <key column="category_id"></key>
15                 <one-to-many class="com.suxiaolei.hibernate.pojos.Category"/>
16             </set>
17             
18             <many-to-one name="parentCategory" class="com.suxiaolei.hibernate.pojos.Category" column="category_id">
19             </many-to-one>
20             
21         </class>
22     </hibernate-mapping>

外键存放父亲的主键。

4. 多对多关系

多对多关系也很常见,例如学生与选修课之间的关系,一个学生可以选择多门选修课,而每个选修课又可以被多名学生选择。数据库中的多对多关联关系一般需采用中间表的方式处理,将多对多转化为两个一对多。

多对多关系在hbm文件中的配置信息:

学生:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 3 <hibernate-mapping>
 4     <class name="com.suxiaolei.hibernate.pojos.Student" table="student">
 5         <id name="id" type="integer">
 6             <column name="id"></column>
 7             <generator class="increment"></generator>
 8         </id>
 9 
10         <property name="name" column="name" type="string"></property>
11 
12         <set name="courses" inverse="false" cascade="save-update" table="student_course">
13             <key column="student_id"></key>
14             <many-to-many class="com.suxiaolei.hibernate.pojos.Course"
15                 column="course_id"></many-to-many>
16         </set>
17     </class>
18 </hibernate-mapping>

课程:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 3 <hibernate-mapping>
 4     <class name="com.suxiaolei.hibernate.pojos.Course" table="course">
 5         <id name="id" type="integer">
 6             <column name="id"></column>
 7             <generator class="increment"></generator>
 8         </id>
 9 
10         <property name="name" column="name" type="string"></property>
11 
12         <set name="students" inverse="true" cascade="save-update" table="student_course">
13             <key column="course_id"></key>
14             <many-to-many class="com.suxiaolei.hibernate.pojos.Student"
15                 column="student_id"></many-to-many>
16         </set>
17     </class>
18 </hibernate-mapping>

其实多对多就是两个一对多,在多对多的关系设计中,一般都会使用一个中间表将他们拆分成两个一对多。<set>标签中的"table"属性就是用于指定中间表的。中间表一般包含两个表的主键值,该表用于存储两表之间的关系。由于被拆成了两个一对多,中间表是多方,它是使用外键关联的,<key>是用于指定外键的,用于从中间表取出相应的数据。中间表每一行数据只包含了两个关系表的主键,要获取与自己关联的对象集合,还需要取出由外键所获得的记录中的另一个主键值,由它到对应的表中取出数据,填充到集合中。<many-to-many>中的"column"属性是用于指定按那一列的值获取对应的数据。

  例如用course表来说,它与student表使用一个中间表student_course关联。如果要获取course记录对应的学生记录,首先需要使用外键"course_id"从student_course表中取得相应的数据,然后在取得的数据中使用"student_id"列的值,在student表中检索出相关的student数据。其实,为了便于理解,你可以在使用course表的使用就把中间表看成是student表,反之亦然。这样就可以使用一对多的思维来理解了,多方关联一方需要外键那么在本例子中就需要"course_id"来关。

5. 一对一关系

一对一关系就球队与球队所在地之间的关系,一支球队仅有一个地址,而一个地区也仅有一支球队(貌似有点勉强,将就下吧)。数据表间一对一关系的表现有两种,一种是外键关联,一种是主键关联。图示如下:

一对一外键关联:

技术分享

技术分享

一对一外键关联在hbm文件中的配置信息:

地址:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 3 <hibernate-mapping>
 4     <class name="com.suxiaolei.hibernate.pojos.Adress" table="adress">
 5         <id name="id" type="integer">
 6             <column name="id"></column>
 7             <generator class="increment"></generator>
 8         </id>
 9 
10         <property name="city" column="city" type="string"></property>
11         
12         <one-to-one name="team" class="com.suxiaolei.hibernate.pojos.Team" cascade="all"></one-to-one>
13 
14     </class>
15 </hibernate-mapping>

球队:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 3 <hibernate-mapping>
 4     <class name="com.suxiaolei.hibernate.pojos.Team" table="team">
 5         <id name="id" type="integer">
 6             <column name="id"></column>
 7             <generator class="increment"></generator>
 8         </id>
 9 
10         <property name="name" column="name" type="string"></property>
11         
12         <many-to-one name="adress" class="com.suxiaolei.hibernate.pojos.Adress" column="adress_id" unique="true"></many-to-one>
13 
14     </class>
15 </hibernate-mapping>

一对一外键关联,其实可以看做是一对多的一种特殊形式,多方退化成一。多方退化成一只需要在<many-to-one>标签中设置"unique"="true"。
一对一主键关联在hbm文件中的配置信息:

地址:

 1 <hibernate-mapping>
 2     <class name="com.suxiaolei.hibernate.pojos.Adress" table="adress">
 3         <id name="id" type="integer">
 4             <column name="id"></column>
 5             <generator class="increment"></generator>
 6         </id>
 7 
 8         <property name="city" column="city" type="string"></property>
 9         
10         <one-to-one name="team" class="com.suxiaolei.hibernate.pojos.Team" cascade="all"></one-to-one>
11 
12     </class>
13 </hibernate-mapping>

球队:

 1 <hibernate-mapping>
 2     <class name="com.suxiaolei.hibernate.pojos.Team" table="team">
 3         <id name="id" type="integer">
 4             <column name="id"></column>
 5             <generator class="foreign">
 6                 <param name="property">adress</param>
 7             </generator>
 8         </id>
 9 
10         <property name="name" column="name" type="string"></property>
11         
12         <one-to-one name="adress" class="com.suxiaolei.hibernate.pojos.Adress" cascade="all"></one-to-one>
13 
14     </class>
15 </hibernate-mapping>

一对一主键关联,是让两张的主键值一样。要使两表的主键相同,只能一张表生成主键,另一张表参考主键。

<generator class="foreign">

  <param name="property">adress</param>

</generator>

"class"="foreign"就是设置team表的主键参照adress属性的主键值。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。