public class User {
@ManyToMany
@JoinTable(name = "t_user_roles",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles = new HashSet<>();
}
public class Role {
@Enumerated(EnumType.STRING)
@Column(length = 20)
private RoleType roleName;
}
public enum RoleType {
ROLE_CUSTOMER("Customer"),
ROLE_MANAGER("Manager"),
ROLE_ADMIN("Administrator");
private String name;
private RoleType(String name) {
this.name=name;
}
public String getName() {
return name;
}
public PageImpl<UserDTO> getAllUserPage(String query,RoleType role,Pageable pageable) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> criteriaQuery = cb.createQuery(User.class);
Root<User> root = criteriaQuery.from(User.class);
List<Predicate> predicates = new ArrayList<>();
Predicate finalPredicate = null;
if (query != null && !query.isEmpty()) {
String likeSearchText = "%" + query.toLowerCase(Locale.US) + "%";
Predicate searchByUserFirstName = cb.like(cb.lower(root.get("firstName")), likeSearchText);
Predicate searchByUserLastName = cb.like(cb.lower(root.get("lastName")), likeSearchText);
Predicate searchByUserEmail = cb.like(cb.lower(root.get("email")), likeSearchText);
predicates.add(cb.or(searchByUserFirstName,searchByUserLastName,searchByUserEmail));
}
---------------------------------------------------------------------------------------------------
if (role != null){
Join<User, Role> joinRoles = root.join("roles");
predicates.add(cb.equal(joinRoles.get("roleName"), role));
System.err.println(role);
}
---------------------------------------------------------------------------------------------------
finalPredicate = cb.and(predicates.toArray(new Predicate[0]));
criteriaQuery.orderBy(pageable.getSort().stream()
.map(order -> {
if (order.isAscending()) {
return cb.asc(root.get(order.getProperty()));
} else {
return cb.desc(root.get(order.getProperty()));
}
})
.collect(Collectors.toList()));
criteriaQuery.where(finalPredicate);
TypedQuery<User> typedQuery = entityManager.createQuery(criteriaQuery);
typedQuery.setFirstResult((int)pageable.getOffset());
typedQuery.setMaxResults(pageable.getPageSize());
CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
countQuery.select(cb.count(countQuery.from(User.class)));
countQuery.where(finalPredicate);
Long totalRecords = entityManager.createQuery(countQuery).getSingleResult();
List<UserDTO> userDTOList = userMapper.map(typedQuery.getResultList());
return new PageImpl<>(userDTOList, pageable, totalRecords);
}
你好朋友,
正如您在上面看到的,我一直在尝试编写一个适用于所有可能场景的 Criteria API 查询。在此查询中,搜索部分完全动态地工作,并在所有可能的情况下提供结果。如果我不发送任何数据,它会带来所有用户。但是,我在添加用于根据角色执行搜索的代码块时遇到了问题。我在这里包含了所有代码,因为我认为其他查询可能存在问题。如您所见,我有 User 和 Role 类。我只裁剪了与角色相关的必要部分以使其简短。在多对多的关系中,我在网上搜索了如何根据用户的角色获取用户,但无济于事。角色在 Role 类中保存为 ENUM。该值没有问题,但是当我执行查询时,我得到错误
"org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.roleName' [select count(generatedAlias0) from com.gpm.domains.User as generatedAlias0 where generatedAlias1.roleName=:param0]"
。尽管字段名称是正确的,但我无法以任何方式获得任何结果。你能帮帮我吗?