SpringData专题(十二)-SpringDataJPA多对多关联

网友投稿 624 2022-09-10

SpringData专题(十二)-SpringDataJPA多对多关联

SpringData专题(十二)-SpringDataJPA多对多关联

1.示例分析

我们采用的示例为用户和角色。 用户:指的是咱们班的每一个同学。 角色:指的是咱们班同学的身份信息。 比如A同学,它是我的学生,其中有个身份就是学生,还是家里的孩子,那么他还有个身份是子女。 同时B同学,它也具有学生和子女的身份。 那么任何一个同学都可能具有多个身份。同时学生这个身份可以被多个同学所具有。 所以我们说,用户和角色之间的关系是多对多。

2.表关系建立

3.实体类关系建立以及映射配置

一个用户可以具有多个角色,所以在用户实体类中应该包含多个角色的信息,代码如下:

一个角色可以赋予多个用户,所以在角色实体类中应该包含多个用户的信息,代码如下:

@Entity@Table(name = "sys_role")public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "role_id") private Long roleId; @Column(name = "role_name") private String roleName; //配置多对多 @ManyToMany(mappedBy = "roles") //配置多表关系 private Set users = new HashSet<>(); public Long getRoleId() { return roleId; } public void setRoleId(Long roleId) { this.roleId = roleId; } public String getRoleName() { return roleName; } public void setRoleName(String roleName) { this.roleName = roleName; } public Set getUsers() { return users; } public void setUsers(Set users) { this.users = users; }}

4.映射的注解说明

@ManyToMany 作用:用于映射多对多关系 属性: cascade:配置级联操作。 fetch:配置是否采用延迟加载。 targetEntity:配置目标的实体类。映射多对多的时候不用写。@JoinTable 作用:针对中间表的配置 属性: nam:配置中间表的名称 joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段 inverseJoinColumn:中间表的外键字段关联对方表的主键字段@JoinColumn 作用:用于定义主键字段和外键字段的对应关系。 属性: name:指定外键字段的名称 referencedColumnName:指定引用主表的主键字段名称 unique:是否唯一。默认值不唯一 nullable:是否允许为空。默认值允许。 insertable:是否允许插入。默认值允许。 updatable:是否允许更新。默认值允许。 columnDefinition:列的定义信息。

5.多对多的操作

5.1.保存

/** * 需求: * 保存用户和角色 * 要求: * 创建2个用户和3个角色 * 让1号用户具有1号和2号角色(双向的) * 让2号用户具有2号和3号角色(双向的) * 保存用户和角色 * 问题: * 在保存时,会出现主键重复的错误,因为都是要往中间表中保存数据造成的。 * 解决办法: * 让任意一方放弃维护关联关系的权利 */ @Test @Transactional //开启事务 @Rollback(false)//设置为不回滚 public void test1(){ //创建对象 User u1 = new User(); u1.setUserName("用户1"); Role r1 = new Role(); r1.setRoleName("角色1"); //建立关联关系 u1.getRoles().add(r1); r1.getUsers().add(u1); //保存 roleDao.save(r1); userDao.save(u1); } } //测试级联添加(保存一个用户的同时保存用户的关联角色) @Test @Transactional @Rollback(false) public void testCasCadeAdd() { 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); }

在多对多(保存)中,如果双向都设置关系,意味着双方都维护中间表,都会往中间表插入数据,中间表的2个字段又作为联合主键,所以报错,主键重复,解决保存失败的问题:只需要在任意一方放弃对中间表的维护权即可,推荐在被动的一方放弃,配置如下:

//配置多对多 @ManyToMany(mappedBy = "roles") //配置多表关系 private Set users = new HashSet<>();

5.2.删除

/** * 案例:删除id为1的用户,同时删除他的关联对象 */ @Test @Transactional @Rollback(false) public void testCasCadeRemove() { //查询1号用户 User user = userDao.findOne(1l); //删除1号用户 userDao.delete(user); }

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:「运维有小邓」用户个人资料管理
下一篇:Redis专题(四)-Redis基本操作命令
相关文章

 发表评论

暂时没有评论,来抢沙发吧~