`

Hibernate 关联

阅读更多

1、hibernate多对一关联映射
关联映射的本质:
* 将关联关系映射到数据库,所谓的关联关系是对象模型在内存中的一个或多个引用
User.java里面包含Group.java定义的group应用

Java代码 复制代码
  1. User.java:   
  2.         private int id;   
  3.     private String name;   
  4.     private Group group;   
  5. -------------------------------------   
  6. Group.java:   
  7.         private int id;   
  8.     private String name;  
User.java:
        private int id;
	private String name;
	private Group group;
-------------------------------------
Group.java:
        private int id;
	private String name;


<many-to-one>会在多的一端加入一个外键,指向一的一端,这个外键是由<many-to-one>
中的column属性定义的,如果忽略了这个属性那么默认的外键与实体的属性一致

<many-to-one>标签的定义示例:
* <many-to-one name="group" column="groupid"/>
例:User.hbm.xml配置:

Java代码 复制代码
  1. <hibernate-mapping>   
  2.     <class name="com.hibernate.User" table="t_user">   
  3.         <id name="id">   
  4.             <generator class="native"/>   
  5.         </id>   
  6.         <property name="name"/>   
  7.         <!-- 理解级联的含义是对象的连锁操作   
  8.         <many-to-one name="group" column="groupid" cascade="all"/>   
  9.          -->   
  10.          <many-to-one name="group" column="groupid"/>   
  11.     </class>   
  12. </hibernate-mapping>   
  13.   
  14. 数据库里是t_user表里创建groupid 字段,并创建一个外键,groupid字段reference t_group表里的id字段。  
<hibernate-mapping>
	<class name="com.hibernate.User" table="t_user">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<!-- 理解级联的含义是对象的连锁操作
		<many-to-one name="group" column="groupid" cascade="all"/>
		 -->
		 <many-to-one name="group" column="groupid"/>
	</class>
</hibernate-mapping>

数据库里是t_user表里创建groupid 字段,并创建一个外键,groupid字段reference t_group表里的id字段。



2、hihernate一对多关联映射(单向Classes----->Student)

一对多关联映射利用了多对一关联映射原理
区别:
多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一
一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多
也就是说一对多和多对一的映射策略是一样的,只是站的角度不同

Java代码 复制代码
  1. Classes.java:   
  2.        private int id;   
  3.        
  4.     private String name;   
  5.        
  6.     private Set students;    
  7. -----------------------------   
  8. Student.java   
  9.         private int id;   
  10.        
  11.     private String name;  
Classes.java:
       private int id;
	
	private String name;
	
	private Set students; 
-----------------------------
Student.java
        private int id;
	
	private String name;


classes.hbm.xml的配置:

Java代码 复制代码
  1. <hibernate-mapping package="com.hibernate">   
  2.     <class name="Classes" table="t_classes">   
  3.         <id name="id">   
  4.             <generator class="native"/>   
  5.         </id>   
  6.         <property name="name"/>   
  7.         <set name="students">   
  8.             <key column="classesid"/>   
  9.             <one-to-many class="Student"/>   
  10.         </set>   
  11.     </class>   
  12. </hibernate-mapping>   
  13.   
  14. 数据库里:t_student表里创建classesid字段,并创建外键,classesid字段reference t_classes表里的id;  
<hibernate-mapping package="com.hibernate">
	<class name="Classes" table="t_classes">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="students">
			<key column="classesid"/>
			<one-to-many class="Student"/>
		</set>
	</class>
</hibernate-mapping>

数据库里:t_student表里创建classesid字段,并创建外键,classesid字段reference t_classes表里的id;



在一一端维护关系的缺点:
* 如果将t_student表里的classesid字段设置为非空,则无法保存
* 因为不是在student这一端维护关系,所以student不知道是哪个班的,
  所以需要发出多余的update语句来更新关系

3.hihernate一对多关联映射(双向Classes<----->Student)
一对多双向关联映射:
* 在一一端的集合上使用<key>,在对方表中加入一个外键指向一一端
* 在多一端采用<many-to-one>

注意:<key>标签指定的外键字段必须和<many-to-one>指定的外键字段一致,否则引用字段的错误

如果在”一“一端维护一对多关联关系,hibernate会发出多余的udpate语句,所以我们一般在多
的一端来维护关联关系

关于inverse属性:
inverse主要用在一对多和多对多双向关联上,inverse可以被设置到集合标签<set>上,
默认inverse为false,所以我们可以从”一“一端和”多“一端维护关联关系,
如果设置成inverse为true,则我们只能从多一端来维护关联关系

注意:inverse属性,只影响数据的存储,也就是持久化

inverse和cascade
* inverse是关联关系的控制方向
* cascade操作上的连锁反应

Java代码 复制代码
  1. Classes.java   
  2.     private int id;   
  3.     private String name;   
  4.     private Set students;   
  5. ------------------------------   
  6. Student.java   
  7.     private int id;   
  8.     private String name;   
  9.     private Classes classes;   
  10. ------------------------------   
  11. Classes.hbm.xml配置:   
  12. <hibernate-mapping package="com.hibernate">   
  13.     <class name="Classes" table="t_classes">   
  14.         <id name="id">   
  15.             <generator class="native"/>   
  16.         </id>   
  17.         <property name="name"/>   
  18.         <set name="students" inverse="true" cascade="all">   
  19.             <key column="classesid"/>   
  20.             <one-to-many class="Student"/>   
  21.         </set>   
  22.     </class>   
  23. </hibernate-mapping>   
  24. --------------------------------   
  25. Student.hbm.xml配置   
  26. <hibernate-mapping>   
  27.     <class name="com.hibernate.Student" table="t_student">   
  28.         <id name="id">   
  29.             <generator class="native"/>   
  30.         </id>   
  31.         <property name="name"/>   
  32.         <many-to-one name="classes" column="classesid"/>   
  33.     </class>   
  34. </hibernate-mapping>   
  35.   
  36. 数据库里:t_student表里创建classesid字段,并创建外键,classesid字段reference t_classes表里的id;  
Classes.java
	private int id;
	private String name;
	private Set students;
------------------------------
Student.java
 	private int id;
	private String name;
	private Classes classes;
------------------------------
Classes.hbm.xml配置:
<hibernate-mapping package="com.hibernate">
	<class name="Classes" table="t_classes">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="students" inverse="true" cascade="all">
			<key column="classesid"/>
			<one-to-many class="Student"/>
		</set>
	</class>
</hibernate-mapping>
--------------------------------
Student.hbm.xml配置
<hibernate-mapping>
	<class name="com.hibernate.Student" table="t_student">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<many-to-one name="classes" column="classesid"/>
	</class>
</hibernate-mapping>

数据库里:t_student表里创建classesid字段,并创建外键,classesid字段reference t_classes表里的id;



4、hibernate一对一主键关联映射(单向关联Person---->IdCard)
一对一主键关联映射:让两个实体对象的id保持相同,这样可以避免多余的字段被创建

Java代码 复制代码
  1. Person.java   
  2.     private int id;   
  3.     private String name;   
  4.     private IdCard idCard;    
  5. -----------------------------   
  6. Person.hbm.xml   
  7. <hibernate-mapping>   
  8.     <class name="com.hibernate.Person" table="t_person">   
  9.         <id name="id">   
  10. <!-- person的主键来源idCard,也就是共享idCard的主键 -->   
  11.             <generator class="foreign">   
  12.                 <param name="property">idCard</param>   
  13.             </generator>   
  14.         </id>   
  15.         <property name="name"/>   
  16. <!-- one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,   
  17.     constrained="true", 表明当前主键上存在一个约束,person的主键作为外键参照了idCard       
  18.         <one-to-one name="idCard" constrained="true"/>   
  19.     </class>   
  20. </hibernate-mapping>   
  21. -----------------------------   
  22. IdCard.java   
  23.     private int id;   
  24.     private String cardNo;   
  25. -----------------------------   
  26. IdCard.hbm.xml   
  27. <hibernate-mapping>   
  28.     <class name="com.hibernate.IdCard" table="t_idcard">   
  29.         <id name="id">   
  30.             <generator class="native"/>   
  31.         </id>   
  32.         <property name="cardNo"/>   
  33.     </class>   
  34. </hibernate-mapping>   
  35.   
  36. 数据库里: t_person的主键来源t_idcard,也就是共享t_idcard的主键,数据库里不例外增加一作为外键的字段。  
Person.java
	private int id;
	private String name;
	private IdCard idCard; 
-----------------------------
Person.hbm.xml
<hibernate-mapping>
	<class name="com.hibernate.Person" table="t_person">
		<id name="id">
<!-- person的主键来源idCard,也就是共享idCard的主键 -->
			<generator class="foreign">
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"/>
<!-- one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,
	constrained="true",	表明当前主键上存在一个约束,person的主键作为外键参照了idCard	
		<one-to-one name="idCard" constrained="true"/>
	</class>
</hibernate-mapping>
-----------------------------
IdCard.java
	private int id;
	private String cardNo;
-----------------------------
IdCard.hbm.xml
<hibernate-mapping>
	<class name="com.hibernate.IdCard" table="t_idcard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
	</class>
</hibernate-mapping>

数据库里: t_person的主键来源t_idcard,也就是共享t_idcard的主键,数据库里不例外增加一作为外键的字段。




5、hibernate一对一主键关联映射(双向关联Person<---->IdCard)
需要在idcard映射文件中加入<one-to-one>标签指向person,指示hibernate如何加载person
默认根据主键加载

Java代码 复制代码
  1. Person.java   
  2.     private int id;   
  3.     private String name;   
  4.     private IdCard idCard;   
  5. -----------------------------   
  6. Person.hbm.xml配置   
  7. <hibernate-mapping>   
  8.     <class name="com.hibernate.Person" table="t_person">   
  9.         <id name="id">   
  10. <!-- person的主键来源idCard,也就是共享idCard的主键 -->   
  11.             <generator class="foreign">   
  12.                 <param name="property">idCard</param>   
  13.             </generator>   
  14.         </id>   
  15.         <property name="name"/>   
  16. <!-- one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,   
  17.     constrained="true", 表明当前主键上存在一个约束,person的主键作为外键参照了idCard       
  18.      -->   
  19.         <one-to-one name="idCard" constrained="true"/>   
  20.     </class>   
  21. </hibernate-mapping>   
  22. -----------------------------   
  23. IdCard.java   
  24.     private int id;   
  25.     private String cardNo;   
  26.     private Person person;   
  27. -----------------------------   
  28. IdCard.hbm.xml   
  29. <hibernate-mapping>   
  30.     <class name="com.hibernate.IdCard" table="t_idcard">   
  31.         <id name="id">   
  32.             <generator class="native"/>   
  33.         </id>   
  34.         <property name="cardNo"/>   
  35.         <one-to-one name="person"/>   
  36.     </class>   
  37. </hibernate-mapping>   
  38.   
  39. 数据库里: t_person的主键来源t_idcard,也就是共享t_idcard的主键,数据库里不例外增加一作为外键的字段。  
Person.java
	private int id;
	private String name;
	private IdCard idCard;
-----------------------------
Person.hbm.xml配置
<hibernate-mapping>
	<class name="com.hibernate.Person" table="t_person">
		<id name="id">
<!-- person的主键来源idCard,也就是共享idCard的主键 -->
			<generator class="foreign">
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"/>
<!-- one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,
	constrained="true",	表明当前主键上存在一个约束,person的主键作为外键参照了idCard	
	 -->
		<one-to-one name="idCard" constrained="true"/>
	</class>
</hibernate-mapping>
-----------------------------
IdCard.java
	private int id;
	private String cardNo;
	private Person person;
-----------------------------
IdCard.hbm.xml
<hibernate-mapping>
	<class name="com.hibernate.IdCard" table="t_idcard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
		<one-to-one name="person"/>
	</class>
</hibernate-mapping>

数据库里: t_person的主键来源t_idcard,也就是共享t_idcard的主键,数据库里不例外增加一作为外键的字段。



6.hibernate一对一唯一外键关联映射(单向关联Person---->IdCard)

一对唯一外键关联映射是多对一关联映射的特例

可以采用<many-to-one>标签,指定多的一端的unique=true,这样就限制了多的一端的多重性为一
通过这种手段映射一对一唯一外键关联

Java代码 复制代码
  1. Person.xml   
  2.     private int id;   
  3.     private String name;   
  4.     private IdCard idCard;   
  5. ------------------------------   
  6. Person.hbm.xml   
  7.  <hibernate-mapping>   
  8.     <class name="com.hibernate.Person" table="t_person">   
  9.         <id name="id">   
  10.             <generator class="native"/>   
  11.         </id>   
  12.         <property name="name"/>   
  13.         <[color=red]many-to-one name[/color]="idCard" [color=red]unique="true"[/color]/>   
  14.     </class>   
  15. </hibernate-mapping>   
  16. ------------------------   
  17. IdCard.java   
  18.     private int id;   
  19.     private String cardNo;   
  20. ------------------------   
  21. IdCard.hbm.xml   
  22. <hibernate-mapping>   
  23.     <class name="com.hibernate.IdCard" table="t_idcard">   
  24.         <id name="id">   
  25.             <generator class="native"/>   
  26.         </id>   
  27.         <property name="cardNo"/>   
  28.     </class>   
  29. </hibernate-mapping>   
  30. 数据库里:t_person里产生一个idcard的外键,reference t_idcard表里的主键id。并指定这个字段为unique(核心:就是many-to-one,只不过外键被约束为唯一的。),  
Person.xml
	private int id;
	private String name;
	private IdCard idCard;
------------------------------
Person.hbm.xml
 <hibernate-mapping>
	<class name="com.hibernate.Person" table="t_person">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<[color=red]many-to-one name[/color]="idCard" [color=red]unique="true"[/color]/>
	</class>
</hibernate-mapping>
------------------------
IdCard.java
	private int id;
	private String cardNo;
------------------------
IdCard.hbm.xml
<hibernate-mapping>
	<class name="com.hibernate.IdCard" table="t_idcard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
	</class>
</hibernate-mapping>
数据库里:t_person里产生一个idcard的外键,reference t_idcard表里的主键id。并指定这个字段为unique(核心:就是many-to-one,只不过外键被约束为唯一的。),



7、hibernate一对一唯一外键关联映射(双向关联Person<---->IdCard)

一对一唯一外键关联双向,需要在另一端(idcard),添加<one-to-one>标签,指示hibernate如何加载
其关联对象,默认根据主键加载person,外键关联映射中,因为两个实体采用的是person的外键维护的关系,
所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射方式:
<one-to-one name="person" property-ref="idCard"/>

Java代码 复制代码
  1. Person.java   
  2.         private int id;   
  3.     private String name;   
  4.     private IdCard idCard;   
  5. ------------------------------   
  6.  <hibernate-mapping>   
  7.     <class name="com.hibernate.Person" table="t_person">   
  8.         <id name="id">   
  9.             <generator class="native"/>   
  10.         </id>   
  11.         <property name="name"/>   
  12.         <many-to-one name="idCard" unique="true"/>   
  13.     </class>   
  14. </hibernate-mapping>   
  15. ------------------------------   
  16. IdCard.java   
  17.     private int id;   
  18.     private String cardNo;   
  19.     private Person person;   
  20. ------------------------------   
  21. <hibernate-mapping>   
  22.     <class name="com.hibernate.IdCard" table="t_idcard">   
  23.         <id name="id">   
  24.             <generator class="native"/>   
  25.         </id>   
  26.         <property name="cardNo"/>   
  27.         <one-to-one name="person" property-ref="idCard"/>   
  28.     </class>   
  29. </hibernate-mapping>   
  30.   
  31. 数据库里:  
Person.java
        private int id;
	private String name;
	private IdCard idCard;
------------------------------
 <hibernate-mapping>
	<class name="com.hibernate.Person" table="t_person">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<many-to-one name="idCard" unique="true"/>
	</class>
</hibernate-mapping>
------------------------------
IdCard.java
	private int id;
	private String cardNo;
	private Person person;
------------------------------
<hibernate-mapping>
	<class name="com.hibernate.IdCard" table="t_idcard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
		<one-to-one name="person" property-ref="idCard"/>
	</class>
</hibernate-mapping>

数据库里:



8、hibernate多对多关联映射(单向User---->Role)

具体映射方式:
<set name="roles" table="t_user_role">
<key column="userid"/>
<many-to-many class="com.hibernate.Role" column="roleid"/>
</set>

Java代码 复制代码
  1. User.java   
  2.     private int id;   
  3.     private String name;   
  4.     private Set roles;    
  5. ----------------------------   
  6. User.hbm.xml   
  7. <hibernate-mapping>   
  8.     <class name="com.hibernate.User" table="t_user">   
  9.         <id name="id">   
  10.             <generator class="native"/>   
  11.         </id>   
  12.         <property name="name"/>   
  13.         <set name="roles" table="t_user_role">   
  14.             <key column="userid"/>   
  15.             <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/>   
  16.         </set>   
  17.     </class>   
  18. </hibernate-mapping>   
  19. ----------------------------   
  20. Role.java   
  21.     private int id;   
  22.     private String name;   
  23. ----------------------------   
  24. Role.hbm.xml   
  25. <hibernate-mapping>   
  26.     <class name="com.hibernate.Role" table="t_role">   
  27.         <id name="id">   
  28.             <generator class="native"/>   
  29.         </id>   
  30.         <property name="name"/>   
  31.     </class>   
  32. </hibernate-mapping>   
  33.   
  34.   
  35. 数据库里:产生第三个表,t_user_role,有2个字段分别为:userid和roleid  
User.java
	private int id;
	private String name;
	private Set roles; 
----------------------------
User.hbm.xml
<hibernate-mapping>
	<class name="com.hibernate.User" table="t_user">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="roles" table="t_user_role">
			<key column="userid"/>
			<many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/>
		</set>
	</class>
</hibernate-mapping>
----------------------------
Role.java
	private int id;
	private String name;
----------------------------
Role.hbm.xml
<hibernate-mapping>
	<class name="com.hibernate.Role" table="t_role">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
	</class>
</hibernate-mapping>


数据库里:产生第三个表,t_user_role,有2个字段分别为:userid和roleid



9.hibernate多对多关联映射(双向User<---->Role)

映射方法:
<set name="roles" table="t_user_role">
<key column="userid"/>
<many-to-many class="com.hibernate.Role" column="roleid"/>
</set>
table属性值必须和单向关联中的table属性值一致
<key>中column属性值要与单向关联中的<many-to-many>标签中的column属性值一致
在<many-to-many>中的column属性值要与单向关联中<key>标签的column属性值一致

Java代码 复制代码
  1. Person.java   
  2.         private int id;   
  3.     private String name;   
  4.     private Set roles;    
  5.   
  6. <hibernate-mapping>   
  7.     <class name="com.hibernate.User" table="t_user">   
  8.         <id name="id">   
  9.             <generator class="native"/>   
  10.         </id>   
  11.         <property name="name"/>   
  12.         <set name="roles" table="t_user_role">   
  13.             <key column="userid"/>   
  14.             <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/>   
  15.         </set>   
  16.     </class>   
  17. </hibernate-mapping>   
  18. ---------------------------------------------   
  19. Role.java   
  20.     private int id;   
  21.     private String name;   
  22.     private Set users;   
  23.   
  24. <hibernate-mapping>   
  25.     <class name="com.hibernate.Role" table="t_role">   
  26.         <id name="id">   
  27.             <generator class="native"/>   
  28.         </id>   
  29.         <property name="name"/>   
  30.         <set name="users" table="t_user_role" order-by="userid">   
  31.             <key column="roleid"/>   
  32.             <many-to-many class="com.bjsxt.hibernate.User" column="userid"/>   
  33.         </set>   
  34.     </class>   
  35. </hibernate-mapping>   
  36.   
  37. 数据库里:  
Person.java
        private int id;
	private String name;
	private Set roles; 

<hibernate-mapping>
	<class name="com.hibernate.User" table="t_user">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="roles" table="t_user_role">
			<key column="userid"/>
			<many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/>
		</set>
	</class>
</hibernate-mapping>
---------------------------------------------
Role.java
	private int id;
	private String name;
	private Set users;

<hibernate-mapping>
	<class name="com.hibernate.Role" table="t_role">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<set name="users" table="t_user_role" order-by="userid">
			<key column="roleid"/>
			<many-to-many class="com.bjsxt.hibernate.User" column="userid"/>
		</set>
	</class>
</hibernate-mapping>

数据库里:


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics