栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用条件实施搜索过滤器

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用条件实施搜索过滤器

如果您想创建非常特殊的过滤器,我相信您应该从发明搜索界面开始。例如这样的:

GET /models?name=eq(john smith)&createdAt=between(2019-01-01,2019-01-31)GET /models?name=like(sm)&createdAt=from(2019-01-01)GET /models?name=sw(john)&createdAt=to(2019-01-31)

之后,您将可以尝试实现它。

IMO解决此类任务的最佳方法是使用Spring Data JPA
规范(和JPA Criteria API)。例如:

1)让我们创建一个为我们的实体

Filter
实现的类:
Specification``Model

@Valuepublic class ModelFilter implements Specification<Model> {    private String name;    private String createdAt;    @Override    public Predicate toPredicate(Root<Model> root, CriteriaQuery<?> query, CriteriaBuilder builder) {        List<Predicate> predicates = new ArrayList<>();        // Prepare predicates and fill the list with them...        return builder.and(predicates.toArray(new Predicate[0]));    }}

2)然后创建一个控制器方法:

@GetMappingpublic List<Model> getAllByFilter(ModelFilter filter) {    return repo.findAll(filter); }

剩下要做的就是准备我们的谓词))

为此,我们可以先创建一个方便的“谓词生成器”界面:

@FunctionalInterfaceinterface PredicateBuilder<T> {    Optional<Predicate> get(String fieldName, String value, Root<T> root, CriteriaBuilder builder);    static Matcher getMatcher(String op, String value) {        return getMatcher(op, value, "(.+)");    }    static Matcher getMatcher(String op, String value, String pattern) {        return Pattern.compile(op + "\(" + pattern + "\)").matcher(value);    }}

然后尝试使我们的谓词:

等于

PredicateBuilder<Model> eq = (fieldName, value, root, cb) -> {    Matcher m = getMatcher("eq", value);    if (m.matches()) {        return Optional.of(cb.equal(cb.upper(root.get(fieldName)), m.group(1).toUpperCase()));    } else {        return Optional.empty();    }};

喜欢

PredicateBuilder<Model> like = (fn, value, root, cb) -> {    Matcher m = getMatcher("like", value);    if (m.matches()) {        return Optional.of(cb.like(cb.upper(root.get(fn)), "%" + m.group(1).toUpperCase() + "%"));    } else {        return Optional.empty();    }};

从…开始

PredicateBuilder<Model> sw = (fn, value, root, cb) -> {    Matcher m = getMatcher("sw", value);    if (m.matches()) {        return Optional.of(cb.like(cb.upper(root.get(fn)), m.group(1).toUpperCase() + "%"));    } else {        return Optional.empty();    }};

之间

PredicateBuilder<Model> between = (fn, value, root, cb) -> {    Matcher m = getMatcher("between", value, "(.+)\s*,\s*(.+)");    if (m.matches()) {        LocalDate from = LocalDate.parse(m.group(1));        LocalDate to = LocalDate.parse(m.group(2));        return Optional.of(cb.between(root.get(fn), from, to));    } else {        return Optional.empty();    }};

PredicateBuilder<Model> from = (fn, value, root, cb) -> {    Matcher m = getMatcher("from", value);    if (m.matches()) {        LocalDate from = LocalDate.parse(m.group(1));        return Optional.of(cb.greaterThanOrEqualTo(root.get(fn), from));    } else {        return Optional.empty();    }};

PredicateBuilder<Model> to = (fn, value, root, cb) -> {    Matcher m = getMatcher("to", value);    if (m.matches()) {        LocalDate to = LocalDate.parse(m.group(1));        return Optional.of(cb.lessThanOrEqualTo(root.get(fn), to));    } else {        return Optional.empty();    }};

剩下的只是完成

Filter
课程:

@Valuepublic class ModelFilter implements Specification<Model> {    private String name;    private String createdAt;    PredicateBuilder<Model> eq = ... ;    PredicateBuilder<Model> like = ... ;    PredicateBuilder<Model> sw = ... ;    PredicateBuilder<Model> between = ... ;    PredicateBuilder<Model> from = ... ;    PredicateBuilder<Model> to = ... ;    @Override    public Predicate toPredicate(Root<Model> root, CriteriaQuery<?> query, CriteriaBuilder builder) {        List<Predicate> predicates = new ArrayList<>();        if (name != null) { eq.get("name", name, root, builder).ifPresent(predicates::add); like.get("name", name, root, builder).ifPresent(predicates::add); sw.get("name", name, root, builder).ifPresent(predicates::add);        }        if (createdAt != null) { between.get("createdAt", createdAt, root, builder).ifPresent(predicates::add); from.get("createdAt", createdAt, root, builder).ifPresent(predicates::add); to.get("createdAt", createdAt, root, builder).ifPresent(predicates::add);        }        return builder.and(predicates.toArray(new Predicate[0]));    }}

当然,这只是实现的一个例子。您可以创建自己的规范和谓词实现。这里的主要内容是:

  • 提出您的搜索界面
  • 制定您的“过滤器”规范
  • 准备您需要的所有谓词
  • 在控制器方法中使用过滤器规范


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/443239.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号