在两张表的多对多操作时,要创建第三张表,至少有两个字段作为外键,指向另外两个表的主键。
表的多对多映射配置
以用户和角色为例子
1、创建实体类,用户和角色实体类
2、让两个实体类互相进行表示
- 一个用户有多个角色,使用set集合
- 一个角色有多个用户,也使用set集合
用户实体类:
package com.demo.entity;
import java.util.HashSet;
import java.util.Set;
//用户实体类
public class User {
private Integer user_id;
private String user_name;
private String user_password;
//一个用户可以有多个角色
private Set<Role> setRole = new HashSet<Role>();
public Set<Role> getSetRole() {
return setRole;
}
public void setSetRole(Set<Role> setRole) {
this.setRole = setRole;
}
public Integer getUser_id() {
return user_id;
}
public void setUser_id(Integer user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_password() {
return user_password;
}
public void setUser_password(String user_password) {
this.user_password = user_password;
}
}
角色实体类:
package com.demo.entity;
import java.util.HashSet;
import java.util.Set;
//角色实体类
public class Role {
private Integer role_id;
private String role_name;
private String role_memo;//角色描述
//一个角色可以有多个用户
private Set<User> setUser = new HashSet<User>();
public Set<User> getSetUser() {
return setUser;
}
public void setSetUser(Set<User> setUser) {
this.setUser = setUser;
}
public Integer getRole_id() {
return role_id;
}
public void setRole_id(Integer role_id) {
this.role_id = role_id;
}
public String getRole_name() {
return role_name;
}
public void setRole_name(String role_name) {
this.role_name = role_name;
}
public String getRole_memo() {
return role_memo;
}
public void setRole_memo(String role_memo) {
this.role_memo = role_memo;
}
}
3、配置映射关系
- 基本配置
- 配置多对多关系
-- 在用户中表示所有角色,使用set标签
用户(User)实体类映射配置文件:
-- 在角色中表示所有用户 ,也使用set标签
角色(Role)实体类映射配置文件:
set标签配置重点:当前配置文件中的key标签中column属性表示的是自己对应第三张表中的外键名称,many-to-many标签中column属性表示的是当前表关联的那张表在第三张表中的外键名称
4、在核心配置文件中引入映射文件
<!-- 第三部分:把映射文件放到核心配置文件中 -->
<mapping resource="com/demo/entity/User.hbm.xml"/>
<mapping resource="com/demo/entity/Role.hbm.xml"/>
多对多级联操作
级联保存
- 根据用户保存角色,一个用户可以有多个不同的角色
(1)在用户(User)映射配置文件中的set标签中设置cascade属性,值为save-update
<set name="setRole" table="t_user_role" cascade="save-update">
(2)代码测试
-- 创建用户和角色对象,将角色对象保存到用户对象中去,最终用session保存用户对象
//测试多对多级联保存
@Test
public void testSave(){
Session session = null;
Transaction tx = null;
try{
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//创建用户和角色对象
User user1 = new User();
user1.setUser_name("张三");
user1.setUser_password("123");
User user2 = new User();
user2.setUser_name("李四");
user2.setUser_password("456");
Role role1 = new Role();
role1.setRole_name("老板");
role1.setRole_memo("老板就是老板");
Role role2 = new Role();
role2.setRole_name("保安");
role2.setRole_memo("保安就是保安");
Role role3 = new Role();
role3.setRole_name("秘书");
role3.setRole_memo("秘书就是秘书");
//建立关系,把角色对象放到用户里
//user1对应role1和role2两个角色,user2对应role2和role3两个角色,到达模拟出多对多关系的效果
user1.getSetRole().add(role1);
user1.getSetRole().add(role2);
user2.getSetRole().add(role2);
user2.getSetRole().add(role3);
//保存用户对象
session.save(user1);
session.save(user2);
tx.commit();
}
catch(Exception e){
tx.rollback();
}
finally{
session.close();
}
}
测试角色中保存用户操作与之类似
级联删除
- 删除一个用户和该用户对应的所有角色
(1)在set标签的cascade属性中添加delete
<set name="setRole" table="t_user_role" cascade="save-update,delete">
(2)删除用户对象
//测试多对多级联删除
@Test
public void testDelete(){
Session session = null;
Transaction tx = null;
try{
session = HibernateUtils.getSession();
tx = session.beginTransaction();
//获取用户对象
User user1 = session.get(User.class, 1);
//删除所获取的用户对象
session.delete(user1);
tx.commit();
}
catch(Exception e){
tx.rollback();
}
finally{
session.close();
}
}
结果发现:所获取的用户对象user1所对应的所有角色role1和role2都被删除了,但与此同时,原来表中的user2对象所对应的角色role2和role3只剩下了role3,因为在联级删除时直接删除了角色(Role)表中的role2对象,所以user2的对应关系被破坏了
维护第三张表关系
为了解决上面所述的问题,我们只用操作第三张表,来维护用户(User)和角色(Role)之间的关系,不用去操作用户表和角色表。
- 为某个用户添加角色
(1)根据id查询用户和角色对象
(2)将角色对象添加到用户对象的set集合中
//查询出user1
User user1 = session.get(User.class, 1);
//查询出role3
Role role3 = session.get(Role.class, 3);
//给user1加入role3角色,将角色加入到用户的set集合中去
user1.getSetRole().add(role3);
- 为某个用户删除角色
(1)根据id查询用户和角色对象
(2)将角色对象从用户的set集合中删除
//查询出user1
User user1 = session.get(User.class, 1);
//查询出role2
Role role2 = session.get(Role.class, 2);
//从user1的角色集合中删除role2
user1.getSetRole().remove(role2);