首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解决Spring中N个搜索案例的最佳实践是什么?

解决Spring中N个搜索案例的最佳实践是什么?
EN

Stack Overflow用户
提问于 2022-05-14 13:56:24
回答 1查看 41关注 0票数 0

解决N次搜索案件数量的最佳做法是什么?

我有三个搜索条件。有A、B和C的搜索条件。

在这种情况下,可能的情况是只搜索A,只搜索B,只搜索C,只搜索AB,只搜索AC,只搜索BC搜索,只搜索ABC。

在上述情况下,共有6宗这样的个案。(3!)

不假思索地绘制出所有病例的数量。

代码语言:javascript
复制
@GetMapping("/A/{A}/B/{B}/C/{C}")
public ReturnType MethodName(@PathVariable AClass A
                             @PathVariable BClass B,
                             @PathVariable CClass C) {
return service.findByAandBandC(A, B, C);
...

我必须创建6个控制器方法,如上面的一个。

代码语言:javascript
复制
With 4 search conditions, need 24 methods (4! = 4 * 3 * 2)

If there are 5 search conditions, need 120 methods (5! = 5 * 4 * 3 * 2)

如前所述,它呈指数增长。

我不知道是否有最佳实践,而不是把所有的情况都变成一种方法。

如果可能的话,任何使用spring数据jpa的答案都将不胜感激。

诚挚的问候!

EN

回答 1

Stack Overflow用户

发布于 2022-05-15 03:03:27

不要为每个搜索选项创建不同的控制器,而是尝试使用一个控制器。假设您有一个端点来获取所有用户的列表。

代码语言:javascript
复制
@GetMapping
public List<User> listAll() {
    return service.listAll();
}

接受地图中的查询参数是一个很好的解决方案。更改方法签名并将查询参数映射传递给服务:

代码语言:javascript
复制
@GetMapping
public List<User> listAll(@RequestParam Map<String, String> queryParams) {
    return service.listAll(queryParams);
}

这样,您就可以接受动态数目的搜索选项。在您的服务类中,使用Spring规范。要执行规范,您的存储库接口需要扩展JpaSpecificationExecutor<T>接口。

代码语言:javascript
复制
public List<User> listAll(Map<String, String> queryParams) {
    return repository.findAll(createSpec(queryParams));
}

private Specification<User> createSpec(Map<String, String> queryParams) {
        return (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            String value = queryParams.get("email");
            if(StringUtils.isNotBlank(value)) {
                Predicate email = criteriaBuilder.like(root.get("email"), "%" + value + "%");
                predicates.add(name);
            }

            value = queryParams.get("name");
            if(StringUtils.isNotBlank(value)) {
                Predicate name = criteriaBuilder.like(root.get("name"), "%" + value + "%");
                predicates.add(name);
            }

            return criteriaBuilder.and(predicates.toArray(Predicate[]::new));
        };
    }

当需要添加更多的搜索选项时,您可以在createSpec()方法中添加它们,而不破坏现有的API协议或添加更多的方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72240897

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档