Hibernate 关系映射之多对多关联
现实中的对象之前的关系大多是多对多的关系,因为一对一,多对一,一对多的关系都可以归结到多对多关系的一种特殊情况。
多对多关系实现的方式:
新建一张中间表,2个字段外键关联对应2张表的id,用2个多对一的关系实现多对多关联。
一、多对多单向关联
场景:以用户(User)和角色(Role)关系为例 。
一个用户对应多种角色,一种角色对应多个用户。
- 对象关联
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuIjY0UWN2IDOiFWZ20yYiRDOtkDMjNTLmVmMh1SZ4IWZ1cjY38CX1cjM28CX4kDMw8CX05WZth2YhRHdh9CXkF2bsBXdvwVbvNmLllXZ0lmLywGZvw1LcpDc0RHaiojIsJye.png)
实体类User
public class User {
private int id;
private String name;
private Set<Role> roles;
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(Stringname) {this.name = name;}
public Set<Role> getRoles() {return roles;}
public void setRoles(Set<Role> roles) {this.roles = roles;}
}
实体类Role
public class Role {
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(Stringname) { this.name = name;}
}
- 关系模型
- 关联映射
1.xml方式
在 一方添加<set>标签 映射多对多(映射set集合),name=集合对象,然后在用<key>标签定义外键。<many-to-many>标签设置映射的类实体
<!--Role.hbm.xml-->
<class name="com.yk.hibernate.Role" table="role">
<id name="id">
<generator class="native"/>
</id>
<property name="name" column="name"/>
</class>
<!--User.hbm.xml-->
</span><class name="com.yk.hibernate.User" table="user">
<id name="id">
<generator class="native"/>
</id>
<property name="name" column="name"/>
<set name="users" table="user_role"order-by="userId"></span>
<key column="role_id"/>
<many-to-many class="com.yk.hibernate.User" column="user_id"/>
</set>
</class>
2.annotation方式
在一方类 的“多(set<E>)”对象getter方法上添加注解@ManyToMany 注解,并使用@JoinTabel来注解第三方表的名称,再使用joinColumns属性来指定当前对象User在中间表中的字段名, 再用inverseJoinColumns来指定当前类持有引用的实体对象Role在中间表的字段名,并且指向被引用对象相对应的表,如下:
@ManyToMany
@JoinTable(name="user_role",
joinColumns={@JoinColumn(name="user_id")},
inverseJoinColumns={@JoinColumn(name="role_id")}
)
public Set<User> getRoles() {return roles;}
二、多对多双向关联
场景:以上述场景为例
- 对象模型:同上
- 关系模型:同上
- 关联映射
1.xml方式:
在单向关联的基础上,在另一个映射文件建立同样的many-to-many标签
<!--User.hbm.xml-->
<class name="com.yk.hibernate.User" table="user">
<id name="id">
<generator class="native"/>
</id>
<property name="name" column="name"/>
<set name="users" table="user_role"order-by="userId">
<key column="role_id"/>
<many-to-many class="com.yk.hibernate.User" column="user_id"/>
</set>
</class>
2.annotation方式
多对多关联映射 双向 两方都持有对象引用,修改对象模型,但数据的存储没有变化
只需要修改注解映射就可以了。
在单向关联的基础上,另一个类的Set<E>对象上加上注释mappedBy
User.java
@ManyToMany
@JoinTable(name="user_role",
joinColumns={@JoinColumn(name="user_id")},
inverseJoinColumns={@JoinColumn(name="role_id")}
)
public Set<User> getRoles() {return roles;}
Role.java
@ManyToMany(mappedBy="roles")
public Set<User>getUsers() {return users;}