1.对于数据库中表的建立
查看文章:SSM中多表的关系和建立
2.实体类的操作
在多对多(保存)中,如果双向都设置关系,意味着双方都维护中间表,都会往中间表插入
数据,中间表的2个字段又作为联合主键,所以报错,主键重复,解决保存失败的问题:
只需要在任意一方放弃对中间表的维护权即可,推荐在被动的一方放弃,所以在Role实体
类中使用的是mappedBy注解。
2.1为角色的实体类添加的注解为:
public class Role {
...
*配置多对多, mappedBy:对方配置关系的属性名称\
@ManyToMany(mappedBy = "roles") //配置多表关系
private Set<User> users = new HashSet<>();
...
}
2.2为用户的实体类添加的注解:
* cascade : 配置级联(可以配置到设置多表的映射关系的注解上)
* CascadeType.all : 所有操作
* MERGE :更新
* PERSIST :保存
* REMOVE :删除
* 配置用户到角色的多对多关系
* 配置多对多的映射关系
* 1.声明表关系的配置
* @ManyToMany(targetEntity = Role.class) //多对多
* targetEntity:代表对方的实体类字节码
* 2.配置中间表(包含两个外键)
* @JoinTable
* name : 中间表的名称
* joinColumns:配置当前对象在中间表的外键
* @JoinColumn的数组
* name:外键名
* referencedColumnName:参照的主表的主键名
* inverseJoinColumns:配置对方对象在中间表的外键
*/
@ManyToMany(targetEntity = Role.class,cascade = CascadeType.ALL)
@JoinTable(name = "sys_user_role",
//joinColumns,当前对象在中间表中的外键
joinColumns = {@JoinColumn(name = "sys_user_id",referencedColumnName = "user_id")},
//inverseJoinColumns,对方对象在中间表的外键
inverseJoinColumns = {@JoinColumn(name = "sys_role_id",referencedColumnName = "role_id")}
)
private Set<Role> roles = new HashSet<>();
3实现逻辑操作
3.1实现RoleDao接口
public interface RoleDao extends JpaRepository<Role,Long> ,JpaSpecificationExecutor<Role> {
}
实现UserDao接口
public interface UserDao extends JpaRepository<User,Long> ,JpaSpecificationExecutor<User> {
}
3.2实现添加操作
/**
* 保存一个用户,保存一个角色
*
* 多对多放弃维护权:被动的一方放弃
*/
@Test
@Transactional
@Rollback(false)
public void testAdd() {
User user = new User();
user.setUserName("小李");
Role role = new Role();
role.setRoleName("java程序员");
//配置用户到角色关系,可以对中间表中的数据进行维护 1-1
user.getRoles().add(role);
//配置角色到用户的关系,可以对中间表的数据进行维护 1-1
role.getUsers().add(user);
userDao.save(user);
roleDao.save(role);
}
3.3删除操作
@Test
@Transactional //配置事务
@Rollback(false) //不自动回滚
public void testCascadeRemove() {
//1.查询1号客户
Customer customer = customerDao.findOne(1l);
//2.删除1号客户
customerDao.delete(customer);
}