1、多对多表的保存操作

实体类:

@Entity
@Table(name = "sys_user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="user_id")
    private Long userId;
    @Column(name="user_name")
    private String userName;
    @Column(name="age")
    private Integer age;

    /**
     * 配置用户到角色的多对多关系
     *      配置多对多的映射关系
     *          @ManyToMany(targetEntity = Role.class)  //多对多
     *                  targetEntity:代表对方的实体类字节码
     *          @JoinTable:配置中间表(包含两个外键)
     *                  1、name:中间表的名称
     *                  2、joinColumns:配置当前对象在中间表的外键
     *                      @JoinColumn的数组:当前对象在中间表中的外键
     *                                1、name:外键名
     *                                2、referencedColumnName:参照的主表的主键名
     *                  3、inverseJoinColumns:配置对方对象在中间表的外键
     *                      @JoinColumn的数组:当前对象在中间表中的外键
     *                                1、name:外键名
     *                                2、referencedColumnName:参照对方的主表的主键名
     */
    @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<Role>();
	//getter and setter toString...
}
@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<User> users = new HashSet<User>();
	//getter and setter toString...
}

测试方法:

/**
     *  保存一个用户,保存一个角色
     *  多对多放弃维护权:被动的一方放弃
     */
    @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);
    }

上面的测试方法可以正常保存数据到三张表中。但是在Role 类中放弃了多对多的维护关系,所以当使用role.getUsers().add(user);注释掉user.getRoles().add(role);时,再执行保存操作,则中间表将没有数据。当两个类中都存在多对多关系的维护的时候,刚刚提到的两条语句同时存在,则向中间表保存数据时会出现异常,主键重复都是1-1

2、级联添加

因为多对多关系的维护时在User类中所以保存时使用role.getUsers().add(user);将不会保存user和中间表信息

//测试级联添加(保存一个用户的同时保存用户的关联角色)
    @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);
    }
3、级联删除
@Test
@Transactional
@Rollback(false)
public void  testCascadeRemove() {
    //查询1号用户
    User user = userDao.findOne(1l);
    //删除1号用户
    userDao.delete(user);
}

发送了三条delete语句,删除三张表中的数据

spring boot jpa 多对一 如何查询 spring data jpa 多对多_外键