Hibernate关联关系配置

开发 后端
本文将详细的介绍Hibernate关联关系的配置,包括一对多、一对一、和多对多的关系。详细请看下文。

第一种关联关系:一对多(多对一)

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

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

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

一对多关系在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> 

外键存放父亲的主键。

第二种关联关系:多对多

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

数据表间多对多关系如下图:

多对多关系在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"来关。

第三种关联关系:一对一

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

一对一外键关联:

 

一对一主键关联:要求两个表的主键必须完全一致,通过两个表的主键建立关联关系:

一对一外键关联在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> 

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

  1. <generator class="foreign"> 
  2.   <param name="property">adress</param> 
  3. </generator> 

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

原文链接:http://www.cnblogs.com/otomedaybreak/archive/2012/01/20/2327695.html

【编辑推荐】

  1. Hibernate中inverse属性与cascade属性
  2. Hibernate复合主键映射
  3. Hibernate继承映射
  4. Hibernate事务与并发问题处理
  5. 让Hibernate显示SQL语句的绑定参数值
责任编辑:林师授 来源: 音①晓的博客
相关推荐

2009-09-25 12:59:52

Hibernate映射

2009-09-25 15:34:42

Hibernate关联

2012-02-08 13:34:08

HibernateJava

2009-07-02 09:40:14

Hibernate的继

2009-09-25 10:22:35

Hibernate多表

2009-09-25 10:47:25

Hibernate延迟

2009-06-02 14:46:26

Hibernate关系映射教程

2009-09-23 13:26:10

Hibernate对象

2012-02-08 12:17:38

HibernateJava

2009-06-18 14:22:06

Hibernate多对Hibernate

2010-07-08 15:28:39

UML类图依赖关系

2010-07-09 15:29:51

UML类关系

2012-02-06 13:52:32

HibernateJava

2012-03-21 11:43:41

JavaHibernate

2010-07-08 14:58:29

UML类图关系

2010-07-07 10:54:53

UML关联关系

2010-06-12 15:04:43

UML关联

2009-06-04 10:34:19

Hibernate一对一对多关系配置

2009-06-17 15:52:23

Hibernate查询

2009-09-24 14:28:23

Hibernate抓取
点赞
收藏

51CTO技术栈公众号