三大框架SSH成长路程(七)

一对多关联映射(七)

一对多关联映射

映射原理

  一对多关联映射和多对一关联映射的映射原理是一致的,都是在多的一端加入一个外键,指向一的一端。关联关系都是由多端维护,只是在写映射时发生了变化。

多对一和一对多的区别

     多对一和一对多的区别在于维护的关系不同:

(1)多对一:多端维护一端的关系,在加载多端时,可以将一端加载上来。
(2)一对多:一端维护多端的关系,在加载一端时,可以将多端加载上来。

分类

一对多单向关联映射

对象模型
这里写图片描述

从对象模型中,我们可以看出,Group持有User的一个引用。由于是单向关联,所以数据在加载Group时,会把User加载上来,但是User并不知道Group的存在。

  我们先看一下Group和User的实体,以及映射文件。

Group

package com.liang.hibernate;  
import java.util.Set;  
public class Group {  
    private int id;  
    private String name;  
    private Set users;  

    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 getUsers() {  
        return users;  
    }  
    public void setUsers(Set users) {  
        this.users = users;  
    }  
}  

User

package com.liang.hibernate;  

public class User {  
    private int id;  
    private String name;  

    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;  
    }  
}  

User.hbm.xml

<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<hibernate-mapping>  
    <class name="com.liang.hibernate.User" table="t_user">  
        <id name="id">  
            <generator class="native"/>  
        </id>  
        <property name="name"/>  
    </class>  
</hibernate-mapping>  

Group.hbm.xml

<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<hibernate-mapping>  
    <class name="com.liang.hibernate.Group" table="t_group">  
        <id name="id">  
            <generator class="native"/>  
        </id>  
        <property name="name"/>  
        <!-- users属性,表达的是本对象与User的一对多的关系 -->  
        <set name="users">  
             <!--当前表(Group)的主键-->  
            <key column="groupid"/>  
            <one-to-many class="com.liang.hibernate.User"/>  
        </set>  
    </class>  
</hibernate-mapping>  

生成的表结构和测试数据
这里写图片描述
这里写图片描述

缺点

1)因为多端User不知道Group的存在(也就是User不维护与Group的关系),所以在保存User时,关系字段groupId为null,如果该字段设置为非空,则将无法保存数据。
2)因为User不维护关系,而Group维护关系,Group就会发出多余的update语句,保证Group和User有关系,这样加载Group时才把该Users对应的用户加载上来。

一对多双向关联映射

对象模型

这里写图片描述

双向关联映射对比单向关联映射,对象的加载方向由单向变成了双向。

我们看一下Group和User的实体,映射文件
Group

package com.liang.hibernate;  

import java.util.Set;  

public class Group {  
    private int id;  
    private String name;  
    private Set users;  

    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 getUsers() {  
        return users;  
    }  
    public void setUsers(Set users) {  
        this.users = users;  
    }  
}  

User

package com.liang.hibernate;  

public class User {  
    private int id;  
    private String name;  
    private Group groups;  
    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 getGroups() {  
        return groups;  
    }  
    public void setGroups(Group groups) {  
        this.groups = groups;  
    }  
}  

Group.hbm.xml

<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<hibernate-mapping package="com.liang.hibernate">  
    <class name="Group" table="t_group">  
        <id name="id">  
            <generator class="native"/>  
        </id>  
        <property name="name"/>  
        <!-- 影响控制反转:inverse="false",多的一端维护关系,让一的一端失效 -->  
        <set name="users" inverse="true">  
            <key column="groupid" not-null="true"/>  
            <one-to-many class="User"/>  
        </set>  
    </class>  
</hibernate-mapping>  

User.hbm.xml

<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<hibernate-mapping package="com.liang.hibernate">  
    <class name="User" table="t_user">  
        <id name="id">  
            <generator class="native"/>  
        </id>  
        <property name="name"/>  
        <!-- groups属性,表达的是本对象与Group的多对一的关系 -->  
        <many-to-one name="groups" class="Group" column="groupid"/>  
    </class>  
</hibernate-mapping>  

生成的表和测试数据
这里写图片描述
这里写图片描述

一对多双向关联的映射方式:

1)在一的一端的集合上采用标签,在多的一端加入一个外键
2)在多的一端采用标签
注意:标签和标签加入的字段保持一直,否则会产生数据混乱。

inverse属性:
inverse属性可以用在一对多和多对多双向关联上,inverse属性默认为false,为false表示本端维护关系,如果inverse为true,则本端不能维护关系,会交给另一端维护关系,本端失效。所以一对多关联映射我们通常在多的一端维护关系,让一的一端失效,所以设置为inverse为true。
注意:inverse属性,只影响数据的存储,也就是持久化。

目的

   一对多双向关联映射的目的主要是为了解决一对多单向关联的缺陷而不是需求驱动的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值