我想执行 Spring 数据规范中的子查询。它一定是这样的 SQL 语句:
select u from users u where u.name in (select up.username from users_profiles up where up.profile in ('admin'));
我有 3 个简单的表格:
- 存储用户数据的
users
- 存储用户个人资料类型的
个人资料
users_profiles
用于存储用户和多个配置文件之间的关系
因此,有了配置文件列表,我需要找到拥有这些配置文件的所有用户。
public List<User> getUsersByProfileType(List<String> profileTypes) {
return userRepository.findAll(new Specification<User> () {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final List<Predicate> predicates = new ArrayList<>();
/*
userNamesWithMatchedProfiles = select up.username from users_profiles up where up.profile in profileTypes
*/
List<String> userNamesWithMatchedProfiles = new ArrayList<String>();
predicates.add(root.get("name").in(userNamesWithMatchedProfiles))
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}
});
}
最佳答案
我找到了执行子查询的方法:
public List<User> getUsersByProfileType(List<String> profileTypes) {
return userRepository.findAll(new Specification<User> () {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
final List<Predicate> predicates = new ArrayList<>();
final Subquery<UserProfile> userProfileSubquery = query.subquery(UserProfile.class);
final Root<UserProfile> userProfile = userProfileSubquery.from(UserProfile.class);
// select up.username from users_profiles ...
userProfileSubquery.select(userProfile.get("user").get("name"));
// ... where up.profile in ('admin')
userProfileSubquery.where(cb.trim(userProfile.get("profile").get("id")).in(profileTypes));
// select u from users u where u.name in ...
predicates.add(root.get("name").in(userProfileSubquery));
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}
});
}
关于java - 带有 JPA 子查询的 Spring Data 规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57273864/