Hibernate笔记=>一对多关系的映射

来源:互联网 发布:软件开发绩效考核指标 编辑:程序博客网 时间:2024/05/16 01:23
Many与One的双向性
以Customer与Order为例,一个Customer可能会发出多个Order,从Costomer到Order是一对多的关联,一般来说在Customer类中会有一个Order的list或set来描述这一关系。而从Order到Customer则是多对一的关联,一般在每个Order对象中定义一个Customer类型的变量来引用所关联的Customer对象。
如果这两种关联同时存在,则为双向关联,否则为单向关联。
 
 
多对一的单向关联
在类与类之间各种关系中,多对一关系与DB中的外键关系最为匹配了,因此如果使用单向关联,通常选择多对一关联。即在Order中定义一个Customer类型属性,而在Customer中无需Order的集合属性,两个类如下:
public class Customer implements Serializable{
    //some properties here.
}
 
public class Order implements Serializable{
    private Customer customer;
    //some other properties here.
    public Customer getCustomer(){
        return customer;
    }
    public void setCustomer(Customer customer){
        this.customer = customer;
    }
}
MappingXML文件中,Customer类的所有属性与CUSTOMERS表的字段一一对应,所以映射很简单,如上一文中所述即可。
但是Order类中的customer属性的映射稍微麻烦一点,也正是这里的重点,如下:
<many-to-one name="customer" column="CUSTOMER_ID"
     class="mypack.Order"  cascade="save-update" not-null="true"/>
这样,通过<many-to-one>元素建立了customer属性与ORDERS表的外键CUSTOMER_ID之间的映射。
not-null:控制数据完整性
cascade:控制级联保存和更新,决定在持久化Order对象是,是否同时持久化与其关联的Customer对象,它有几个属性可以选择,稍后再专门讨论。
 
 
一对多的单向关联
与多对一关联不同,一对多的关系需要在DB中额外创建关联表,不能简单通过外键来解决了。一对多关系的两个类如下:
public class Customer implements Serializable{
    private Set orders = new HashSet();
    //some other properties here..
    public Set getOrders(){
        return this.orders;
    }
    public void setOrders(Set orders){
        this.orders = orders;
    }
}
 
public class Order implements Serializable{
    //some properties here.
}
MappingXML文件中,Order类的所有属性与ORDERS表的字段一一对应,所以映射很简单。而Customer的配置有些复杂了:
<set name="orders" cascade="save-update" inverse="true">
    <key column="CUSTOMER_ID" />
    <one-to-many class="mypack.Order"><!--定义集合中对象类型-->
</set>
 
 
双向关联
所谓的双向关联,就是以上两种情况同时存在,没有什么特别好说的内容了。:)
值得一提的是同一个类的自身双向管联问题,比如说一个文件系统中的Folder类,它的parent属性和children集合属性所引用的对象全都是Folder类。这与Customer和Order的关系略微有所差别,但是配置也异曲同工,即把Folder的MappingXML中同时设置<set>和<many-to-one>元素即可。
根据经验,
在映射一对多的双向关联时,应该在many方把inverse属性设置为true,这样可以减少不必要的数据库访问,提高性能。
 
 
级联策略
在Many与One的关系中,级联策略很重要,这关系着效率与完整性等问题。
在<set>、<many-to-one>、<one-to-one>元素中都有一个cascade属性,它用于指定如何操纵与当前对象关联的其他对象。cascade有如下几个可选属性值:
none:是默认值,在保存、更新、删除当前对象时,忽略其他关联对象。
save-update:当通过Session的save()、update()和saveOrUpdate()保存或更新对象时,级联保存所有关联的新建的临时对象,并且级联更新所有关联的游离对象。
delete:当通过Session的delete()删除当前对象时,级联删除所有关联对象。
all:包含save-update和delete的行为。此外,当对当前对象执行evict()或lock()操作时,也会对所有级联的持久化对象执行evict和lock操作。
delete-orphan:删除所有和当前对象接触关联关系的对象。
all-delete_orphan:包含all和delete-orphan的行为。
0 0