您的位置:首页 > 其它

Hibernate映射详解(五)--多对多关联映射 .

2012-05-25 12:40 176 查看
        举个例子来说,就是用户与角色。一个用户可以属于多个角色,而一个角色又可以拥有多个用户。文字表述就是这样了,看一下用图的直观表示。
实体关系图



 

表格关系图



        当关系两方有一端为一时,我们让多的一端维护关系,可以减少数据的冗余,提高效率。那要是多对多的话,如果还在某一方维护数据,那缺点就一点都没有避免。那怎么解决这个问题呢?我们呢采用第三张表格来维护这个关系。即上图中间用户角色表。将关系两方的主键抽离出来放到第三张表中。最大程度的减少冗余性。看一下具体实现。

实体类实现:

publicclass User {
   
    privateintid;
   
    private Stringname;
 
   
privateSetroles; //关联属性

     …省略get,set方法

}

publicclass Role {
 
    privateintid;
   
    private Stringname;

     …省略get,set方法

}

 

对应的映射文件实现

user.hbm.xml

<hibernate-mapping>
    <classname="com.bjpowernode.hibernate.User"table="t_user">
        <idname="id">
            <generatorclass="native"/>
        </id>
        <propertyname="name"/>
        <!--下面这段配置实现了生成第三张表,将user主键与role主键关联起来
-->
        <setname="roles"table="t_user_role">
           <keycolumn="user_id"/>
           <many-to-manyclass="com.bjpowernode.hibernate.Role"column="role_id"/>   
       </set>
    </class>
</hibernate-mapping>

Role.hbm.xml

<hibernate-mapping>
    <classname="com.bjpowernode.hibernate.Role"table="t_role">
        <idname="id">
            <generatorclass="native"/>
        </id>
        <propertyname="name"/>
    </class>
</hibernate-mapping>

 

 

 

 

看完单向,与前面一样,我们看一下双向。

实体类代码实现:

public class User {
   
    privateintid;
   
    private Stringname;
 
   privateSetroles; //关联属性

    …省略get,set方法

}

public class Role {
 
    privateintid;
   
    private Stringname;
   
   privateSet users; //关联属性

     …省略get,set方法

}

对应的配置文件的实现:

<hibernate-mapping>
    <classname="com.bjpowernode.hibernate.User"table="t_user">
        <idname="id">
            <generatorclass="native"/>
        </id>
        <propertyname="name"/>
       <setname="roles"table="t_user_role">
           <keycolumn="user_id"not-null="true"/>
           <many-to-manyclass="com.bjpowernode.hibernate.Role"column="role_id"/>   
       </set>
    </class>
</hibernate-mapping>

<hibernate-mapping>
    <classname="com.bjpowernode.hibernate.Role"table="t_role">
        <idname="id">
            <generatorclass="native"/>
        </id>
        <propertyname="name"/>
       <setname="users"table="t_user_role">
           <keycolumn="role_id"not-null="true"/>
           <many-to-manyclass="com.bjpowernode.hibernate.User"column="user_id"/>
       </set>
    </class>
</hibernate-mapping>

        多对多双向关联的实现原理也是新增一张表,使两端的主键联系起来。所以,在映射文件的配置时,生成的中间表名称必须是一样的,比如这里的set标签中定义的table字段t_user_role。除了表名称以外,表字段名称也必须是一样的如此处set标签中的column标签的值。

        到现在,关联映射我们就已经介绍完了。通过,这么多映射的比较,他们之间确实是有几点共性的地方。

        假设有关系A,B两端。若A与B有单向关联,即A—>B,则A的实体类中会有B作为他的属性。若B端为一(非多),则A中多一个B类型的属性,若B端为多,则A中多一个Set类型的集合,而它存储的类型当然为B。这跟A端是多或者一是没有关系的。那映射文件呢?若one-to-one或者many-to-one,one端name为另一端实体类中实例化的变量的名字。而若是*-to-many,则many一端name为多的一端的对象类所在的位置。哪个包下边哪个类。若实体中出现了Set类型的属性,那映射文件中对应的也会有Set标签。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息