Kira-2006
-仅仅是一阵风也罢了,偏偏是这样永恒, 仅仅是一场梦也罢了,偏偏是如此的真实,
posts - 4,comments - 7,trackbacks - 0

一对一关联
    主键关联:
即两张表通过主键形成一对一映射关系。

    用户TUser与护照TPassport关联
    TUer.hbm.xml
    
<hibernate-mapping>
<class
    
name="TUser"
    table
="T_User">
    
    
<one-to-one 
        
name="passport"
        class
="TPassport"
        cascade
="all"
        outer-join
="true"/>
    
</class>
</hibernate-mapping>
cascade="all"表示级联关系设置为“all”,即无论主空房执行任何操作,都会关联类执行相同的操作。

    TPassport.hbm.xml
<hibernate-mapping>
<class
    
name="TPassport"
    table
="T_Passport">
    
<one-to-one
        
name="user"
        class
="TUser"
        constrain
="true">
    .
</class>
</hibernate-mapping>

    
constrain必须设定为“true”,以告知Hibernate当前主键上存在一个约束。
   
    测试代码:
TUser user = new TUser();
user.setAge(
new Integer(20));
user.setName(
"Carin");

TPassport passport 
= new TPassport();
passport.setSerial(
"PCN759386");
passport.setExpiry(
new Integer(20080101));

//相互设置关联
passport.setUser(user);
user.setPassport(passport);

Transaction tx 
= sessioin.beginTransaction();
//由于TUser类的one-to-one节点被设置成
//cascade=“all”其关联的passport对象将被级联保存
session.save(user);

tx.commit();
    以下代码完成关联对象的读取:
TUser user=(TUser)Hibernate.load(TUser.class,new Integer(15));
System.out.println(
"User name=>"+user.getName());
System.out.println(
"Passport Serial=>"+user.getPassport().getSerial());
    控制台输出:
Hibernate:select tuser0_.id as id1_,
from T_USER tuser0_
left outer join
T_PASSPORT tpassport1_ on tuser0_.id
=tpassport1_.id
where tuser0_.id
=?
User name
=>Carin
Passport Serial
=>PCN759386
Hibernate通过left outer join将T_User表及其关联的T_Passport表同时读入,因为此时将out-join=“true”。若设置为false,则会分开读取两个表。

一对多关联
    用户TUser和地址TAddress的一对多关联。
    单向一对多关联
        主控方TUser的映射配置:
<hibernate-mapping>
<class
    
name="TUser"
    table
="t_user"
    dynamic-update
="true"
    dynamic-insert
="true">
.
    
<set
        
name="address"
        table
="t_address"
        cascade
="all"
        order-by
="zipcode asc">
        
<key column="user_id"/>
        
<one-to-many class="TAddress">
    
</set>

</class>
</hibernate>
被动方TAddress的记录由Hibernate负责读取,之后存放在主控方TUser指定的Collection类型属性中。
单向一对多的实现比较简单,但是存在一个问题,由于是单向关联,为了保持关联关系,我们只能通过主控方对被动方进行级联更新。如果被关联方的关联字段为“NOT NULL”,当Hibernate创建或者更新时,可能出现约束违例。

双向多对一关联
    实际上是“一对多”与“多对一”关联的组合。也就是说我们必须在主控方配置一对多关系的基础上,在被控方配置与其对应的多对一关联。
    TUser.hbm.xml
<hibernate-mapping>
<class
    
name="TUser"
    table
="t_user"
    dynamic-update
="true"
    dynamic-insert
="true">
.
    
<set
        
name="address"
        table
="t_address"
        lazy
="false"
        inverse
="true"
        cascade
="all"
        sort
="unsorted"
        order-by
="zipcode asc">
        
<key column="user_id"/>
        
<one-to-many class="TAddress"/>
    
</set>
.
</class>
</hibernate>
inverse="true",TUser不在作为主控方,而是将关联关系的维护工作交给关联对象TAddress来做。
在one-to-many关系中,将many一方设置为主控方(inverse=“true”)将有助于性能的改善。
    TAddress.hbm.xml
<hibernat-mapping>
<class
    
name="TAddress"
    table
="t_address"
    dynamic-update
="false"
    dynamic-insert
="false">
.
    
<many-to-one
        
name="user"
        class
="TUser"
        cascade
="none"
        outer-join
="auto"
        update
="true"
        insert
="true"
        access
="property"
        column
="user_id"
        not-null
="true"/>
.
</class>
</hibernate-mapping>

多对多关联
需要借助中间表来完成多对多映射信息的保存。
    由于多对多关联的性能不佳(由于引入了中间表,一次读取操作需要反复多次查询),因此在设计中应该避免大量使用。同时,在多对多关系中,应根据情况,采取延迟加载机制来避免无谓的性能开销。
    TGroup与TRole的多对多关联:
    TGroup.hbm.xml:
<hibernate-mapping>
<class
    
name="TGroup"
    table
="t_group"
    dynamic-update
="false"
    dynamic-insert
="false">
.
    
<set
        
name="roles"
        table
="t_group_role"
        lazy
="false"
        inverse
="false"
        cascade
="save-update">
        
<key column="group_id"/>
        
<many-to-many
            
class="TRole"
            column
="role_id"/>
    
</set>
.
</class>
</hibernate>
t_group_role为t_group与t_role之间的映射表,它保存了group和role之间的映射关系。
cascade=“save-update”,对于多对多逻辑而言,很少出现删除一方需要级联删除所有关联数据的情况,如删除一个group,一般不会删除其中包含的Role。
column=“group_id”映射表中对于t_group表记录的标识字段。
 
    TRole.hbm.xml:
<hibernate-mapping>
<class
    
name="TRole"
    table
="t_role"
    dynamic-update
="false"
    dynamic-insert
="false">
.
    
<set
        
name="groups"
        table
="t_group_role"
        lazy
="false"
        inverse
="true"
        cascade
="save-update"
        sort
="unsorted">
        
<key column="role_id"/>
        
<many-to-many 
            
class="TGroup"
            column
="group_id"
            outer-join
="auto"/>
    
</set>
.
</class>
</hibernate>
多对多关系中,由于关联关系是两张表相互引用,因此在保存关联状态时必须对双方同时保存。
posted on 2008-05-10 20:08 Kira-2006 阅读(528) 评论(0)  编辑  收藏 所属分类: hibernate

只有注册用户登录后才能发表评论。


网站导航: