SSH与SSM学习之hibernate20——多对多操作
一、说明
关于多对多的关系可以查看 SSH与SSM学习之hibernate16——表与表的三种关系。
这里我们涉及到的是 用户(员工)与角色之间的多对多的关系。
二、 用户(员工)实体
2.1 User.java
**
* @author:qiwenming
* @date:2017/9/19 0019 20:57
* @description:
* 用户类
*/
public class User {
private Long user_id;
private String user_code;
private String user_name;
private String user_password;
private Character user_state;
//表达多对多关系
private Set<Role> roles = new HashSet<>();
....省略了get/set方法...
}
2.2 User.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.qwm.hibernate03.domain" >
<class name="User" table="sys_user" >
<id name="user_id" >
<generator class="native"></generator>
</id>
<property name="user_code" ></property>
<property name="user_name" ></property>
<property name="user_password" ></property>
<property name="user_state" ></property>
<!-- 多对多关系表达 -->
<!--
name: 集合属性名
table: 配置中间表名
key
|-column:外键,别人引用"我"的外键列名
class: 我与哪个类是多对多关系
column:外键.我引用比人的外键列名
-->
<set name="roles" table="sys_user_role">
<!---->
<key column="user_id"></key>
<many-to-many class="Role" column="role_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
三、角色实体
3.1 Role.java
public class Role {
private Long role_id;
private String role_name;
private String role_memo;
//表达多对对关系
private Set<User> users = new HashSet<>();
....省略了get/set方法...
}
3.2 Role.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.qwm.hibernate03.domain" >
<class name="Role" table="sys_role" >
<id name="role_id" >
<generator class="native"></generator>
</id>
<property name="role_name" ></property>
<property name="role_memo" ></property>
<!-- 多对多关系表达 -->
<!--
name: 集合属性名
table: 配置中间表名
key
|-column:外键,别人引用"我"的外键列名
class: 我与哪个类是多对多关系
column:外键.我引用比人的外键列名
-->
<set name="users" table="sys_user_role" inverse="true">
<key column="role_id"></key>
<many-to-many class="User" column="user_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
四、保存用户以及角色
4.1 产生的问题以及解决
注意: 这里我们保存用户与角色的数据的时候,需要注意,二者默认都是维护着关系的,就会导致二者都会相互之间添加到维护他们两者之间关系的表中,这样就会产生主键冲突,导致无法数据添加失败。
解决方式有两种:
第一种 我们在添加数据关系的时候,只添加一方的关系,不添添加另一方的关系
如:
//3.3表达关系
user1.getRoles().add(role1);
user1.getRoles().add(role2);
user2.getRoles().add(role1);
user2.getRoles().add(role2);
// role1.getUsers().add(user1);
// role1.getUsers().add(user2);
// role2.getUsers().add(user1);
// role2.getUsers().add(user2);
或者
//3.3表达关系
// user1.getRoles().add(role1);
// user1.getRoles().add(role2);
// user2.getRoles().add(role1);
// user2.getRoles().add(role2);
role1.getUsers().add(user1);
role1.getUsers().add(user2);
role2.getUsers().add(user1);
role2.getUsers().add(user2);
第二种 这种方式就是配置一方放弃维护关系,可以配置到 User 中,也可以配置到 Role中,
如
如果是 Role.hbm.xml
....
<set name="users" table="sys_user_role" inverse="true">
<key column="role_id"></key>
<many-to-many class="User" column="user_id"></many-to-many>
</set>
...
或者
如果是 User.hbm.xml
......
<set name="roles" table="sys_user_role" inverse="true">
<!---->
<key column="user_id"></key>
<many-to-many class="Role" column="role_id"></many-to-many>
</set>
......
下面的例子中,我们采用的是配置文件中 Role放弃维护关系,就是上面我们的完整配置
4.2 代码实例
/**
* 保存用户以及角色
*/
@Test
public void test1(){
//1.创建session
Session session = HibernateUtils.openSession();
//2.开启事务
Transaction t = session.beginTransaction();
//===================================
//3.操作
//3.1创建两个用户
User user1 = new User();
user1.setUser_name("高晓明");
User user2 = new User();
user2.setUser_name("李志锋")
;
//3.2创建两角色
Role role1 = new Role();
role1.setRole_name("保安");
Role role2 = new Role();
role2.setRole_name("清洁工");
//3.3表达关系
user1.getRoles().add(role1);
user1.getRoles().add(role2);
user2.getRoles().add(role1);
user2.getRoles().add(role2);
role1.getUsers().add(user1);
role1.getUsers().add(user2);
role2.getUsers().add(user1);
role2.getUsers().add(user2);
//3.4数据持久化
session.save(user1);
session.save(user2);
session.save(role1);
session.save(role2);
//===================================
//4.提交事务
t.commit();
//5.关闭资源
session.close();
}
4.3 结果
用户表
角色表
用户-角色表
五、为用户添加角色
5.1 问题说明
我们为用户保存角色的时候,有两种方式处理
第一种:我们自己保存角色
例如
user.getRoles().add(role);
session.save(role);
第二种:再我们的user.hbm.xml中配置级联保存
例如
<set name="roles" table="sys_user_role" cascade="save-update">
<!---->
<key column="user_id"></key>
<many-to-many class="Role" column="role_id"></many-to-many>
</set>
这里我们使用的是第一种方式
5.2 示例代码
/**
* 为用户添加角色
* 我们来实现为 “高晓峰”添加一个“部门经理”的角色
*/
@Test
public void test2(){
//1.创建session
Session session = HibernateUtils.openSession();
//2.开启事务
Transaction t = session.beginTransaction();
//===================================
//3.操作
//3.1 得到高晓峰这个用户
User user = session.get(User.class,1L);
//3.2 创建“部门经理”这个角色
Role role = new Role();
role.setRole_name("部门经理");
//3.3 给高晓峰添加“部门经理”这个角色
//这里不用调用保存的方法,保存user,因为user是持久化对象
user.getRoles().add(role);
// session.save(role);
//===================================
//4.提交事务
t.commit();
//5.关闭资源
session.close();
}
5.3 结果
六、为用户删除角色
6.1 示例代码
/**
* 为用户删除角色
* 我们来实现为 “高晓峰”删除“清洁工”和“保安”的角色
*/
@Test
public void test3(){
//1.创建session
Session session = HibernateUtils.openSession();
//2.开启事务
Transaction t = session.beginTransaction();
//===================================
//3.操作
//3.1获取到用户
//3.2获取到“清洁工”这个角色
//3.3获取到“保安”这个角色
//3.4从用户的角色集合中删除“保安”和“清洁工”
User user = session.get(User.class,1L);
Role role1 = session.get(Role.class,1L);
Role role2 = session.get(Role.class,2L);
//user是持久化对象那个,所以不用调用保存的方法
user.getRoles().remove(role1);
user.getRoles().remove(role2);
//===================================
//4.提交事务
t.commit();
//5.关闭资源
session.close();
}