【问题标题】:Need to find all Users for a specific role JPA Criteria API需要查找特定角色的所有用户 JPA Criteria API
【发布时间】:2020-09-03 02:37:58
【问题描述】:

我正在实施具有以下实体的用户管理系统:

public class UserEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    Long id;

    @Column(unique = true, name = "EMAIL")
    private String email;
    @Column(name = "NAME")
    private String name;
    @Column(name = "PASSWORD")
    private String password;
    @Column(name = "MOBILE")
    private String mobile;
    @Column(name = "OWNER_ID")
    private String ownerId;
    @Column(name = "TRAINER_ID")
    private String trainerId;
    @Column(name = "ADDED_ON")
    private Timestamp addedOn;
    @Column(name = "MODIFIED_ON")
    private Timestamp modifiedOn;
    @Column(name = "ADDED_BY")
    private String addedBy;
    @Column(name = "MODIFIED_BY")
    private String modifiedBy;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "USER_ROLES", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"),
            inverseJoinColumns =
            @JoinColumn(name =
                    "ROLE_ID", referencedColumnName = "ROLE_ID"))
    List<RoleEntity> roles;

    @OneToOne(
            mappedBy = "user",
            cascade = CascadeType.ALL,
            orphanRemoval = true,
            fetch = FetchType.LAZY
    )
    private UserStatisticsEntity userStatisticsEntity;

这里是 RoleClass :

public class RoleEntity implements GrantedAuthority {

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

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

    @ManyToMany(mappedBy = "roles")
    private List<UserEntity> users;

    @Override
    public String getAuthority() {
        return this.roleId;
    }
}

我想获取属于特定角色的所有用户,并且还能够在姓名、手机、电子邮件以及寻呼等方面添加动态 where 子句。

我当前的代码看起来像这样使用动态 where 子句和分页来获取用户的选定字段:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

        CriteriaQuery<TrainerDTO> criteriaQuery = criteriaBuilder.createQuery(TrainerDTO.class);
        Root<UserEntity> main = criteriaQuery.from(UserEntity.class);
        criteriaQuery.multiselect(main.get("id"), main.get("name"), main.get("email"), main.get("ownerId"), main.get(
                "mobile"),
                main.get("addedBy"), main.get("modifiedBy"), main.get("addedOn"), main.get("modifiedOn"))
                     .orderBy(criteriaBuilder.desc(main.get("addedOn")))
                     .distinct(true);
        List<Predicate> predicates = new ArrayList<>();
        if (StringUtils.isNotBlank(queryParams.get("mobile"))) {
        predicates.add(criteriaBuilder.and(criteriaBuilder.equal(main.get("mobile"), queryParams.get("mobile"))));
    }
    if (StringUtils.isNotBlank(queryParams.get("name"))) {
        predicates.add(criteriaBuilder.and(criteriaBuilder.like(main.get("name"),
                "%" + queryParams.get("name") + "%")));
    }
    if (StringUtils.isNotBlank(queryParams.get("email"))) {
        predicates.add(criteriaBuilder.and(criteriaBuilder.equal(main.get("email"), queryParams.get("email"))));
    }
        criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
        log.info("TrainerDAO::getAllTrainersPaginatedForOwner Query created...");

        TypedQuery<TrainerDTO> query = entityManager.createQuery(criteriaQuery);
        query.setFirstResult(pageNumber - 1);
        query.setMaxResults(pageSize);
        return query.getResultList();

这里有两个问题:

  1. 如何获取所有具有特定角色的用户?假设我需要查找具有 ROLE_ID = "ROLE_ADMIN" 的角色的所有用户。
  2. 在我的分页实现中,最后一项在下一页重复。假设 User1 是第 1 页上的最后一项,他也将作为第 2 页上的第一项出现。

请就如何进行下一步提出建议。所有帮助将不胜感激。

【问题讨论】:

  • 您好!你用jpa吗?如果是,则在您的存储库中尝试此方法以按角色获取所有用户。 List findAllByRoleEntity(RoleEntity roleEntity);
  • 我还需要根据查询参数和分页添加动态查询。我猜存储库方法在这里没有帮助。

标签: java spring-boot jpa spring-data-jpa criteria-api


【解决方案1】:

我的方式是这样的:

问题 1:

您需要访问 RoleEntity 以检查 role_id 是否等于“ROLE_ADMIN”,因此您需要先从 RoleEntity 获取角色并获取那里的所有信息。

创建 ma​​in 对象后:

Fetch<UserEntity, RoleEntity> fetchedRoles = main.fetch("roles", JoinType.LEFT);
  1. 您将条件附加到您的谓词列表中;
predicates.add(criteriaBuilder.equal( fetchedRoles.get( "roleId" ), "ROLE_ADMIN"));

问题 2:

我将尝试分享在这种情况下我会做些什么来帮助您解决问题。

假设你在这里创建了查询,在这个带有可分页对象的方法中,你想要返回 Page

private Page<Books> getUsersWithAdminRole(String... parameters, Pageable pageable){
  //...

  List<UserEntity> result = entityManager.createQuery(criteria).setFirstResult((int) pageable.getOffset()).setMaxResults(pageable.getPageSize()).getResultList();

  CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
  Root<UserEntity> userCount = countQuery.from(UserEntity.class);
  countQuery.select(criteriaBuilder.count(userCount)).where(criteriaBuilder.and(predicates.toArray(newPredicate[predicates.size()])));
  Long count = entityManager.createQuery(countQuery).getSingleResult();
  Page<UserEntity> userPage = new PageImpl<>(result, pageable, count);
  return userPage;
}

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2012-07-06
    • 2017-11-02
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    相关资源
    最近更新 更多