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

1.简介

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

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

2.创建表

创建用户角色表

spring boot data jpa 一对多 springboot多对多_User


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

spring boot data jpa 一对多 springboot多对多_List_02

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.测试

spring boot data jpa 一对多 springboot多对多_User_03


发现有了当前用户的角色

spring boot data jpa 一对多 springboot多对多_List_04


成功!

7.总结

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

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