我正在实现一个Repository,它实现了QuerydslBinderCustomizer,以帮助从url过滤器参数创建Predicates。就是这样
@NoRepositoryBean
public interface TableRepository<T extends TableEntity, S extends EntityPathBase<T>> extends PagingAndSortingRepository<T, UUID>, QuerydslPredicateExecutor<T>, QuerydslBinderCustomizer<S> {
@Override
default void customize(@NonNull QuerydslBindings bindings, @NonNull S root) {
bindings.bind(String.class).all((MultiValueBinding<StringPath, String>) (path, values) -> {
BooleanBuilder predicate = new BooleanBuilder();
values.forEach(value -> predicate.or(path.containsIgnoreCase(value)));
return Optional.of(predicate);
});
}
}
我的个人实体存储库正在扩展,如
public interface UserRepository extends TableRepository<User, QUser> {
}
这会产生端点http://localhost:port/users
。事情很好,我可以提出http://localhost:port/users?name="somename"
等请求。
现在,我正在实现软删除,我不想在查询时返回软删除的记录。我打算为此编辑customize
方法
default void customize(@NonNull QuerydslBindings bindings, @NonNull S root) {
bindings.bind(String.class).all((MultiValueBinding<StringPath, String>) (path, values) -> {
BooleanBuilder predicate = new BooleanBuilder();
values.forEach(value -> predicate.or(path.containsIgnoreCase(value)));
// If path does not have delete flag, add deleted=false to the predicate
return Optional.of(predicate);
});
}
但是当没有任何参数(即http://localhost:port/users
)对端点进行调用时会出现问题。在这种情况下,bindings.bind()
会被执行但BooleanBuilder predicate = new BooleanBuilder();
部分却不会执行。因此,我无法添加所需的谓词来过滤掉软删除的记录。怎么办?
我可能会以错误的方式过滤删除的记录。还有更好的选择吗?
编辑:根据要求,我正在关联基本存储库https://github.com/SayakMukhopadhyay/demo-querydsl
答案 0 :(得分:1)
所以我想您现在已经找到了解决方案。 但是对于那些试图获得某种“默认谓词”的人来说,这里是一个潜在的解决方案。
就像您的情况一样,我们也进行了软删除,并希望在默认情况下排除它们,除非特别要求。
首先,您不能在自定义方法中设置此项。 这些绑定仅在为条件传递值时触发。由于某些原因,当没有价值时,他们没有提供绑定。 他们可能有充分的理由这样做。 所以在这个方法中你只关心通过的标准。
我们在请求中处理默认值的方式是在调用 findAll 之前修改 Predicate。
控制器签名应该是这样的,带有一个谓词:
@GetMapping
public ResponseEntity<List<User>> searchUsers(
@QuerydslPredicate(root = User.class, bindings = UserRepository.class) Predicate predicate)
您只需要检查谓词中是否包含条件, 如果没有,请自行添加。
if (!ExpressionUtils.extract(predicate).toString().contains("deleted =")) {
predicate = new StringPath("deleted").eq("false").and(predicate);
}
userRepository.findAll(predicate);
如果不存在,应该添加条件,如果存在则忽略。
这显然是一个简化的表示,但想法就在那里。
希望这会有所帮助。