gpt4 book ai didi

spring-boot - 将 WHERE IN 子句添加到 JPA 规范

转载 作者:行者123 更新时间:2023-12-03 18:44:53 25 4
gpt4 key购买 nike

我正在尝试实现受 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");
}

存储库:
@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);
}

用 IN 子句扩展规范的正确方法是什么?
specification.and(path.in(types)) path 是一个属性,但如何正确实现它?

最佳答案

一般可以这样实现:

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();
}
}

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)
}

附言

使用 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)
}

更新:最短路径
@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)
}

关于spring-boot - 将 WHERE IN 子句添加到 JPA 规范,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56959816/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com