Spring Data JPA 多对多实现多表关联查询

需求介绍

角色与用户关系,一个用户可能拥有多个角色,一个角色也能对应多个用户。

主要存在三张表,sys_user(用户表),sys_role(角色表),sys_user_role(用户角色关联表)
在这里插入图片描述

功能实现

实现查询所有用户及所包含的角色权限。

实体类

用户SysUser

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;

/**
 * @Description: 用户
 * @Author: hk
 * @Date: 2020-06-23 22:37:58
 */
@Getter
@Setter
@Entity
@Table(name = "sys_user")
public class SysUser extends AbstractAuditable implements Serializable {

    @Id
    @GenericGenerator(name = "genericGenerator", strategy = "uuid")
    @GeneratedValue(generator = "genericGenerator")
    private Integer id;

    @Column(name = "name")
    private String name;

    @Column(name = "password")
    private String password;

	//单向多对多
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "sys_user_role"
            ,joinColumns = @JoinColumn(name = "user_id",referencedColumnName = "id")
            ,inverseJoinColumns = @JoinColumn(name = "role_id",referencedColumnName = "id"))
    private List<SysRole> roles = new ArrayList<>();
}

注:
@ManyToMany
需要和@JoinTable表结合使用,ManyToMany总是使用中间关系连接表来存储关系。

  1. mappedBy:若关系是双向的则需要使用到。JoinTablce和JoinColumn一般定义在拥有关系的这一端,而mappedBy一定是定义在关系的被拥有方,属性值为中间关联表对应的实体。
  2. cascade
    CascadeType.REFRESH:级联刷新,当多个用户同时作操作一个实体,为了用户取到的数据是实时的,在用实体中的数据之前就可以调用一下refresh()方法
    CascadeType.REMOVE:级联删除,当调用remove()方法删除Order实体时会先级联删除OrderItem的相关数据
    CascadeType.MERGE:级联更新,当调用了Merge()方法,如果Order中的数据改变了会相应的更新OrderItem中的数据
    CascadeType.ALL:包含以上所有级联属性
    CascadeType.PERSIST:级联保存,当调用了Persist() 方法,会级联保存相应的数据

@JoinTable
如果对象与对象之间有一个关联关系表的时候,就会用到@JoinTable

角色SysRole

import javax.persistence.*;
import java.io.Serializable;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;

/**
 * @Description: 角色
 * @Author: hk
 * @Date: 2020-06-23 22:37:57
 */
@Getter
@Setter
@Entity
@Table(name = "sys_role")
public class SysRole extends AbstractAuditable implements Serializable {

    @Id
    @GenericGenerator(name = "genericGenerator", strategy = "uuid")
    @GeneratedValue(generator = "genericGenerator")
    private Integer id;
    
    @Column(name = "name")
    private String name;
    
}

用户角色关联SysUserRole

/**
 * @Description: 用户角色关联
 * @Author: hk
 * @Date: 2020-06-23 22:37:58
 */
@Getter
@Setter
@Entity
@IdClass(value = SysUserRoleKey.class)
@Table(name = "sys_user_role")
public class SysUserRole extends AbstractAuditable implements Serializable  {

    @Id
    @Column(name = "user_id")
    private String userId;

    @Id
    @Column(name = "role_id")
    private String roleId;
            
}

联合主键SysUserRoleKey

import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;

/**
 * @Description: 用户角色联合主键
 * @Author: hk
 * @Date: 2020-06-23 23:02
 */
@Getter
@Setter
public class SysUserRoleKey implements Serializable {

    private String userId;

    private String roleId;

    public SysUserRoleKey(String userId, String roleId) {
        this.userId = userId;
        this.roleId = roleId;
    }

    public SysUserRoleKey() {
    }
}

这边只是简单查询所用用户及具备的角色权限。所以省略server层与dao层

Controller 层
import com.hk.entity.SysUser;
import com.hk.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Description:
 * @Author: hk
 * @Date: 2020-06-23 22:37:58
 */

@RestController
@RequestMapping("sysUser")
public class SysUserController {

    private SysUserService sysUserService;

    @Autowired
    public SysUserController(SysUserService sysUserService) {
        this.sysUserService = sysUserService;
    }

    @RequestMapping(value = "/all")
    public List<SysUser> findAll() {
        return sysUserService.findAll();
    }

}

查询效果

在这里插入图片描述

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值