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

本文介绍了在Hibernate中实现多对多关联映射的方法,包括单向和双向关联的具体实现方式,并详细解释了如何通过创建第三张表来解决多对多关系的数据冗余问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

举个例子来说,就是用户与角色。一个用户可以属于多个角色,而一个角色又可以拥有多个用户。文字表述就是这样了,看一下用图的直观表示。

实体关系图

表格关系图

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

实体类实现:

publicclass User {

privateintid;

private Stringname;

privateSetroles; //关联属性

省略getset方法

}

publicclass Role {

privateintid;

private Stringname;

省略getset方法

}

对应的映射文件实现

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;//关联属性

省略getset方法

}

public class Role {

privateintid;

private Stringname;

privateSet users;//关联属性

省略getset方法

}

对应的配置文件的实现:

<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标签。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值