Pet*_*zov 6 jpa jpa-2.0 spring-data-jpa jpa-2.1 spring-boot
我正在尝试实现受 IN 子句限制的搜索功能:
我想实现带有过滤器限制的搜索实现:
@GetMapping("find")
public Page<MerchantUserDTO> getAllBySpecification(
@And({
@Spec(path = "name", spec = LikeIgnoreCase.class),
@Spec(path = "login", spec = LikeIgnoreCase.class),
@Spec(path = "email", spec = LikeIgnoreCase.class),
}) Specification<Users> specification,
@SortDefault(sort = "login", direction = Sort.Direction.DESC) Pageable pageable
) {
return merchantUserService.getAllBySpecification(specification, pageable)
.map(g -> MerchantUserDTO.builder()
.id(g.getId())
.login(g.getLogin())
.build()
);
}
@Override
public Page<Users> getAllBySpecification(Specification<Users> specification, Pageable pageable) {
return dao.findAllByTypeIn(specification, pageable, "MerchantUser");
}
Run Code Online (Sandbox Code Playgroud)
存储库:
@Repository
public interface MerchantUserRepository extends JpaRepository<Users, Integer>, JpaSpecificationExecutor<Users> {
Page<Users> findAllByTypeIn(Pageable page, String... types);
Page<Users> findAllByTypeIn(Specification<Users> specification, Pageable pageable, String... types);
}
Run Code Online (Sandbox Code Playgroud)
使用 IN 子句扩展规范的正确方法是什么?
specification.and(path.in(types)) path 是一个属性,但如何正确实现它?
Nik*_*nko 12
通常这可以通过以下方式实现:
1) 创建规范实现
public class MerchantUserSpecification implements Specification<Users> {
private final List<String> types;
public MerchantUserSpecification(List<String> types) {
this.types = types;
}
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
if (types != null && !types.isEmpty()) {
return root.get(Users_.type).in(types);
} else {
// always-true predicate, means that no filtering would be applied
return cb.and();
}
}
Run Code Online (Sandbox Code Playgroud)
2) 使用方法Page findAll(@Nullable Specification spec, Pageable pageable); 从JpaSpecificationExecutor接口继承而不是使用您的自定义findAllByTypeIn(Specification<Users> specification....)
@Override
public Page<Users> getAllBySpecification(Specification<Users> specification, Pageable pageable) {
// combine original specification (passed from outside) and filter-by-types specification
Specification<Users> finalSpec = specification
.and(new MerchantUserSpecification(Arrays.asList("MerchantUser")))
return dao.findAll(finalSpec, pageable)
}
Run Code Online (Sandbox Code Playgroud)
聚苯乙烯
对于 Java 8+ 和简单的情况(如您的情况),代码可能会减少得更多。Specification<T>您可以创建一个方法,而不是在单独的类中实现
private Specification<Users> typeIn(List<String> types) {
return (root, query, cb) -> {
if (types != null && !types.isEmpty()) {
return root.get(Users_.type).in(types);
} else {
// always-true predicate, means that no filtering would be applied
return cb.and();
}
}
}
@Override
public Page<Users> getAllBySpecification(Specification<Users> specification, Pageable pageable) {
// combine original specification (passed from outside) and filter-by-types specification
Specification<Users> finalSpec = specification
.and(typeIn(Arrays.asList("MerchantUser")))
return dao.findAll(finalSpec, pageable)
}
Run Code Online (Sandbox Code Playgroud)
更新:最短的方法
@Override
public Page<Users> getAllBySpecification(Specification<Users> specification, Pageable pageable) {
// combine original specification (passed from outside) and filter-by-types specification
Specification<Users> finalSpec = specification
.and((root, query, cb) -> root.get(Users_.type).in(Arrays.asList("MerchantUser"))
return dao.findAll(finalSpec, pageable)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12778 次 |
| 最近记录: |