如何在多对多 spring 关系中查找特定角色

How to find specific roles in many-to-many spring relationship

我有以下实体

@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Entity
public class Role extends AbstractEntity {

  private String name;

  @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE},
  fetch = FetchType.EAGER)
  @JoinTable(
      name = "privilege_roles",
      joinColumns = {@JoinColumn(name = "role_id")},
      inverseJoinColumns = {@JoinColumn(name = "privilege_id")})
  @Exclude
  private Set<Privilege> privileges;

  @ManyToMany(
      cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType},
      fetch = FetchType.LAZY)
  @JoinTable(
      name = "user_roles",
      joinColumns = {@JoinColumn(name = "role_id")},
      inverseJoinColumns = {@JoinColumn(name = "user_id")})
  private Set<User> users;
}

@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Entity
public class Privilege extends AbstractEntity {

  private String name;

  @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
  @JoinTable(
      name = "privilege_roles",
      joinColumns = {@JoinColumn(name = "privilege_id")},
      inverseJoinColumns = {@JoinColumn(name = "role_id")})
  private Set<Role> roles;
}

/** Model użytkownika */
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Entity
public class User extends AbstractEntity {

  private String login;
  private String firstName;
  private String lastName;

  @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
  @JoinTable(
      name = "user_roles",
      joinColumns = {@JoinColumn(name = "user_id")},
      inverseJoinColumns = {@JoinColumn(name = "role_id")})
 
  private Set<Role> roles;
}

抽象实体由 ID 等组成。我的问题是从特定用户那里获得权限,可以通过一个查询来完成吗?在这一点上,我把它分为两个步骤

  Set<Role> findByUsers_Login(String login);
  Set<Privilege> getAllByRolesIdIn(Collection<@Nonnull Integer> roles_id);

我怎样才能实现我的目标,如果注意到任何与清洁代码或性能改进相关的事情,我将不胜感激

HashSet<PrivilegeDto> authorities = new HashSet<>();
UserDto userDto = userService.findByLogin(login)
Set<Long> rolesId = roleService(findByUserId(userDto.getId().stream()
        .map(AbstractDto::getId)
        .collect(Collectors::toSet());
for (Long id : rolesId) {
    Set<PrivilegeDto> privilegesById = privilegeService.getPrivilegesById(id);
    authorities.addAll(privilegesById);
}
@Query(value = "SELECT P.NAME FROM USER_ROLES UR LEFT JOIN PRIVILEGE_ROLES PR ON PR.ROLE_ID = UR.ROLE_ID LEFT JOIN PRIVILEGE P ON PR.PRIVILEGE_ID = P.ID LEFT JOIN USER U ON U.ID = UR.USER_ID WHERE U.LOGIN = :login",nativeQuery = true)
    Set<Privilege> getAllMyPriviliges(@Param("login")String login);

我很难理解您为什么需要第二个查询。对于第一个,您将获得一组 RoleRole 对象已经包含一组 Privilege,您可以使用 getter 方法简单地检索它们,如下所示:

findByUsers_Login(login).stream()
    .flatMap(role -> role.getPrivileges().stream()).collect(Collectors.toSet());