hibernate映射关系 一对多&多对一

    接着上篇博客继续今天的主题:一对多,和多对一的关系映射实现。之所以把这两个关系放在一起说,不考虑方向,一对多和多对一还有区别吗?   

一、一对多 vs 多对一

    相同点:
    映射原理是一致的,都是在多的一端加入一个外键,指向一的一端
    双向关联是一致的。
        
    区别在于维护的关系不同——即单向关联

     多对一维护的关系是:多指向一的关系,有了此关系,在加载多的时候可以将一加载上来
     一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来   

    有了这些认识,我们来看看具体的实现吧。

二、一对多       

    形如班级和学生之间的关系就是一对多,一个班级有多个学生。

    关系图

     


     来看一下实现过程
    1、单向Classes--->Student
    被关联的对象student,不用做改动。
    Class 实体类

   

				public class Classes {	
					private int id;	
					private String name;	
					private Set students;
				
					public int getId() {
						return id;
					}
					public void setId(int id) {
						this.id = id;
					}
					public String getName() {
						return name;
					}
					public void setName(String name) {
						this.name = name;
					}
					public Set getStudents() {
						return students;
					}
					public void setStudents(Set students) {
						this.students = students;
					}	
				}
         class 映射文件           
		<hibernate-mapping>
			<class name="cassie.hibernate.Classes" table="t_classes">
				<id name="id">
					<generator class="native"/>
				</id>
				<property name="name"/>
				<set name="students">
					<!-- <key column="classesid" not-null="true"/> -->
					<key column="classesid"/>
				        <one-to-many class="cassie.hibernate.Student"/>
				</set>
			</class>
		</hibernate-mapping>
        

      单向关联维护关系存在缺陷
    
      1、因为多的一端Student不知道Classes的存在(也就是Student没有维护与Classes的关系),所以在保存Student的时候关系字段classesid是为null的,如果将该关系字段设置为非空,则将无法保存数据。

      2、另外因为Student不维护关系,而Classes维护关系,Classes就会发出多余的update语句,保证Classes和Student有关系,这样加载Classes的时候才可以把该Classes对应的学生加载上来
       

    正因为如此,我们引入了双向关联,一对多的双向关联的出现是为了克服单向的权限而出现的,不是应需求驱动的。
        
    2、双向的实现
        
        映射方式:
            在一的一端的集合上采用<key>标签,在多的一端加入一个外键
            在多的一端采用<many-to-one>标签
            
        注意:<key>标签和<many-to-one>标签加入的字段保持一直,否则会产生数据混乱。       
        Class 不用改动,现在改动student类
        student类

			public class Student {
				private int id;
				private String name;
				private Classes classes;
			
				public int getId() {
					return id;
				}
				public void setId(int id) {
					this.id = id;
				}
				public String getName() {
					return name;
				}
				public void setName(String name) {
					this.name = name;
				}
				public Classes getClasses() {
					return classes;
				}
				public void setClasses(Classes classes) {
					this.classes = classes;
				}
			}
           Student.hbm.xml

			<hibernate-mapping>
				<class name="com.bjpowernode.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> 

    

    3、inverse属性

        inverse属性可以用在一对多和多对多双向关联上,inverse属性默认为false,为
        false表示本端可以维护关系,如果inverse为true,则本端不能维护关系,会交给另一端
        维护关系,本端失效。
        一对多关联映射我们通常在多的一端维护关系,让一的一端失效,所以设置为inverse为true。
        为什么呢?是为了节省数据库资源。
        双方如果都可以维护关系,在进行insert语句时,另一方就势必会有update语句发出,所以省却不必要的update语句,我们一般建议在一对多双向关联关系中,将一方的inverse属性设置为true,即将主外键的关系交由多方来维护。
        打个比方:在一个公司中,是老板认识所有的员工容易,还是所有员工认识老板容易?

        所以在这,我们需要把class维护关系失效

			<hibernate-mapping>
				<class name="com.bjpowernode.hibernate.Classes" table="t_classes">
					<id name="id">
						<generator class="native"/>
					</id>
					<property name="name"/>
					<set name="students" inverse="true">
						<!-- 
						<key column="classesid" not-null="true"/>
						 -->
						 <key column="classesid"/>
						<one-to-many class="com.bjpowernode.hibernate.Student"/>
					</set>
				</class>

</hibernate-mapping>

   

三、多对一

实现:在多的一端加入一个外键,指向一的一端。

约定标签:many-to-one

关系图

       
    单向实现

     User实体类    

				public class User {
				
					private int id;
					
					private String name;
					
					private Group group;
				
					public int getId() {
						return id;
					}
				
					public void setId(int id) {
						this.id = id;
					}
				
					public String getName() {
						return name;
					}
				
					public void setName(String name) {
						this.name = name;
					}
				
					public Group getGroup() {
						return group;
					}
				
					public void setGroup(Group group) {
						this.group = group;
					}
				}
   User.hbm.xml  
				<hibernate-mapping>
					<class name="com.bjpowernode.hibernate.User" table="t_user">
						<id name="id">
							<generator class="native"/>
						</id>
						<property name="name"/>
						<many-to-one name="group" column="groupid" cascade="save-update"/>
					</class>

</hibernate-mapping>
        

      不难发现,多对一的单向的设置,其实就是一对多双向的一部分中的“多的一段的"设置。所以双向多对一,即一对多的双向。这里就不在赘述。


   结语:一对多,和多对一的关系是最常见的关系。双向关联,两者无区别,单向关联的时候,一定要谨慎。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值