- 介绍
- 这种多对多的情况在我们生活中有很多,比如在你上学的时候花的钱是父母的也是你的,说的更准确一些是父母的,钱和我们可以看作是一对多的关系,又比如你拥有很多东西这些东西又被很多人拥有那么你与这些东西之间就是多对多的关系。
- 再举一个例子生活中例子,假如你是高、富、帅或白、瘦、美,说明你同时具有了很多优点,你对应多个优点,但这些优点不是你一个人专有很多人都有,那么它们与人之间就构成了多对多的关系,也希望我们都朝着这个方向发展。
- 又比如一个的职位、角色等很多情况下都不会只是一种,可能一个人即是员工又是经理,身兼数职,在系统中我们常常把这种抽象出来在数据库表中展示出来。
- 这里我们说一下一个人身兼数职这种对应关系如何从实体映射到关系表中。
- 应用场景
- 系统中都会有权限管理模块,谈到权限当然就会涉及到参与的用户与权限对应关系,往往一个用户会有多个角色即多个权限,把用户和角色看成两个实体类可以得到他们的UML类图,如下
- 图
- 从图上可以看出这两个类的多重度都为n,而且是单向关联从用户指向角色,表明知道了一个用户的信息就会得到他的角色信息,反过来不能得到。
- 通常多对多的关系需要引入一个关系表维护两个实体类之间得关系,为什么要引入关系表?如果你看了前两篇博客就会觉得真的有必要引入一张表,多对多是一对多的一个升级,你想想一对多的关系在哪里维护,是在任意一张表里呢,在说的具体一点是在多的一方的表里面加入了一个外键,当这种关系由一对多转为多对多时如果不引入一张表,在少的一方将会出现很多重复记录,因此需要引入一个关系表。
- 这两个类对应的实体以及映射文件为:
- User实体类
package com.bjpowernode.hibernate; import java.util.Set; /** * 用户实体类 * @author LLS * */ public class User { //具有的属性 private int id; private String name; //保存多的一方的实体信息 private Set roles; //getter和setter方法 public Set getRoles() { return roles; } public void setRoles(Set roles) { this.roles = roles; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
- Role实体类
package com.bjpowernode.hibernate; /** * 角色实体类 * @author LLS * */ 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(String name) { this.name = name; } }
- User.hbm.xml映射文件
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.bjpowernode.hibernate.User" table="t_user"> <id name="id"> <generator class="native"> </generator> </id> <property name="name"></property> <!-- 由于这种多对多是单方向的,关系表的维护在用户一端完成。 <key>属性默认会把User表的主键加入关系表中,作为一列 <many-to-many>会关关联表的主键也加入到关联表中 理解了一对多映射,多对多会觉得很简单 --> <set name="roles" table="t_user_role"> <key column="user_id"></key> <many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/> </set> </class> </hibernate-mapping>
- Role.hbm.xml映射文件
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.bjpowernode.hibernate.Role" table="t_role"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <set name="users" table="t_user_role"> <key column="role_id"></key> <many-to-many class="com.bjpowernode.hibernate.User" column="user_id"></many-to-many> </set> </class> </hibernate-mapping>
- 另外在给大家介绍一个MySql数据库客户端,一直看黑乎乎的屏幕也不是很习惯,今天安装了一个客户端工具Msql manager for mysql,很好用。
- 如果想改为双向关联只需要改一改Role配置文件即可,代码如下
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping > <class name="com.bjpowernode.hibernate.Role" table="t_role"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <set name="users" table="t_user_role"> <key column="role_id"></key> <many-to-many class="com.bjpowernode.hibernate.User" column="user_id"></many-to-many> </set> </class> </hibernate-mapping>
- 写的映射和在User端一样,需要注意的是column属性必须与User映射文件中对应,负责会出现错误。
- 系统中都会有权限管理模块,谈到权限当然就会涉及到参与的用户与权限对应关系,往往一个用户会有多个角色即多个权限,把用户和角色看成两个实体类可以得到他们的UML类图,如下
- 其它映射
- 除了一对多、一对一、多对多还有很多映射,例如继承映射、组件映射、主键映射、集合映射等等,就不一一介绍主键映射是组件映射的一种,最重要的还是这三种映射。