【问题标题】:Filter results from QueryDSL search过滤来自 QueryDSL 搜索的结果
【发布时间】:2018-07-26 06:23:38
【问题描述】:

我使用 QueryDSL 作为 Spring Data Rest 的一部分从我们的 API 中搜索实体。

是否有可能以某种方式过滤搜索 API,以便默认情况下它不会找到例如“停用”的 Car 实体?

目前我在汽车实体上有一个标志,当它设置为 true 时,它​​不应该通过我们的搜索 API 公开,并且设置了这个属性的汽车应该被排除在搜索之外。

https://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#core.web.type-safe

【问题讨论】:

标签: spring-boot spring-data-rest querydsl


【解决方案1】:

在使用 Spring Data REST 和 QueryDSL 的情况下,要更改查询的标准行为,我们可以使用方面。

例如:我们需要默认只显示那些flag设置为trueModels:

@Data
@NoArgsConstructor
@Entity
public class Model {

    @Id @GeneratedValue private Integer id;
    @NotBlank private String name;
    private boolean flag;
}

在这种情况下,我们这样实现方面:

@Aspect
@Component
public class ModelRepoAspect {

  @Pointcut("execution(* com.example.ModelRepo.findAll(com.querydsl.core.types.Predicate, org.springframework.data.domain.Pageable))")
  public void modelFindAllWithPredicateAndPageable() {
  }

  @Around("modelFindAllWithPredicateAndPageable()")
  public Object filterModelsByFlag(final ProceedingJoinPoint pjp) throws Throwable {

    Object[] args = pjp.getArgs();
    Predicate predicate = (Predicate) args[0];

    BooleanExpression flagIsTrue = QModel.model.flag.eq(true);

    if (predicate == null) {
        args[0] = flagIsTrue;
    } else {
        if (!predicate.toString().contains("model.flag")) {
            args[0] = flagIsTrue.and(predicate);
        }
    }

    return pjp.proceed(args);
  }
}

这个切面拦截我们repo的方法findAll(Predicate predicate, Pageable pageable)的所有调用,如果请求参数没有设置(predicate == null),或者不包含'flag',则将过滤器model.flag = true添加到查询中范围。否则方面不会修改原来的predicate

【讨论】:

  • 谢谢,这正是我想要的。我必须对其进行测试,但逻辑似乎正是我想要的。我会在尝试后立即将您的答案标记为接受。非常感谢。
  • 由于 QueryDslPredicateExecutor 不提供访问最终谓词的方法,并且 Spring Security PostFilter 不适用于可分页,这实际上是从 QueryDSL 存储库中过滤结果的唯一方法。谢谢!
猜你喜欢
  • 2015-02-09
  • 1970-01-01
  • 2013-02-02
  • 2012-07-05
  • 2017-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多