SpringBoot中使用jpa实现双向多对多(纯注解的实现方式)

mac2025-06-01  4

当前环境:idea 、springboot 当前项目基于前面的项目:SpringBoot中使用jpa实现一对多(或者多对一)的处理(纯注解的实现方式)

1.简介

由于前面实现了多对一和一对多,所以在这里实现多对多双向的,但是如果配置双向的多对多,就会出现一个问题重写toString的问题,需要自定义toString,否者会出现栈溢出的问题!

一个学生可以获得多个角色,一个角色对应多个学生,这就产生了双向多对多的问题,现在用注解实现双向多对多的处理!

2.创建表

创建用户角色表 创建用户角色的关系表:用于描述当前多对多的关系

3.编写实体类

Role类中的内容

import lombok.*; import javax.persistence.*; import java.util.List; /** * Created by admin on 2019/11/1. * 角色表,用于多对多关联映射 */ @Entity @Table(name = "users_role") @NoArgsConstructor @AllArgsConstructor public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Getter @Setter private Integer id; @Column(name = "role_name",nullable = false) @Getter @Setter private String roleName; //一个角色对应多个用户 /* @JoinColumn(name = "uid",table = "users_role_relation")*/ @ManyToMany(targetEntity = User.class) @JoinTable(name = "users_role_relation",joinColumns = {@JoinColumn(name = "rid")},inverseJoinColumns = {@JoinColumn(name = "uid")}) private List<User> users; //由于配置了双向多对多,就会产生一个问题,死递归,出现了问题栈溢出 @Override public String toString() { return "role[id:"+id+",roleName:"+roleName+"]"; } }

当前User类中的内容

import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; import java.util.List; /** * Created by admin on 2019/11/1. * 用于描述当前班级中的学生,一个学生只能在一个班级,但是一个班级具有多个学生,一个学生具有多个角色 */ @Entity @Table(name = "users") @Data @NoArgsConstructor @AllArgsConstructor public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "username", nullable = false) private String username; @Column(name = "password", nullable = false) private String password; @Column(name = "classes_id",nullable = false) private Integer classesId; //由于这里重写了toString所以会产生一个死循环的后果,所以只能配置单项的一对多或者单项的多对一 /* @ManyToOne(targetEntity = Classes.class, fetch = FetchType.LAZY) private Classes classes;*/ //出现了这个错误:Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: com.hy.springboot.demo.entity.User.role // 就是具有mappedBy的语句不能使用@JoinTable或者@JoinColumn注解 :@ManyToMany(targetEntity = Role.class,mappedBy = "id") @ManyToMany(targetEntity = Role.class) @JoinTable(name = "users_role_relation", joinColumns = {@JoinColumn(name = "uid")},inverseJoinColumns=@JoinColumn(name="rid")) private List<Role> roles;

1.当前出现的问题:由于当前我配置了@ManyToMany中添加了MappedBy,结果出现了一个错误:Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn: com.hy.springboot.demo.entity.User.role(其实就是在使用ManyToMany的时候如果添加了MappedBy就不能使用 @JoinTable 或者 @JoinColumn)

2.使用的时候(由于使用了第三张表所以需要使用@JoinTable,所以需要指明当前的表名,并且需要填写当前集合对应的列,必须为当前另外一个多对多的对应表中的uid),两边是相反的

4.创建RoleDao

/** * Created by admin on 2019/11/1. * 当前用于用户的角色,一个角色对应多个用户或者学生,一个学生具有多个角色 */ @Repository public interface RoleDao extends JpaRepository<Role,Integer> { }

5.向MainController中添加方法

@Autowired RoleDao roleDao; @RequestMapping("/roleList") public String findRoleAll(){ List<Role> roleList = roleDao.findAll(); boolean empty = CollectionUtils.isEmpty(roleList); return empty ? "没有数据" : roleList.toString(); }

6.测试

发现有了当前用户的角色 成功!

7.总结

1.当前实现了双向多对多的功能,但是还是有一些需要注意的地方:当前的注解方式使用@ManyToMany,不能指定MappedBy,还要使用@JoinTable中编写内容,注意这里的内容与当前集合的属性相反

2.小心栈溢出的问题,就是toString问题

以上纯属个人见解,如有问题请联系本人!

最新回复(0)