sza*_*kel 3 spring querydsl spring-data-jpa spring-boot
我在我的 Spring Boot 项目中使用QueryDSL并计划使用 Spring 的网络支持(当前查询 dsl web docs)。问题是,我找不到有关使用不同运算符的任何信息。如何定义not equals或matches regex操作?乍一看,它所做的只是将您的?fieldname=value格式GET请求转换为您在存储库中设置的预定义操作。我可以以某种方式扩展它以允许对同一字段进行多次操作吗?
例子。:
目前我可以Predicate通过传递 URL 参数来获取 QueryDsl ,例如?user.company.id=1:
@Controller
class UserController {
@Autowired UserRepository repository;
@RequestMapping(value = "/", method = RequestMethod.GET)
Page<User> getUsers(@QuerydslPredicate(root = User.class) Predicate predicate,
Pageable pageable) {
return repository.findAll(predicate, pageable);
}
}
Run Code Online (Sandbox Code Playgroud)
但正如我链接的文档所述,我只能为某个字段定义一个操作。如果我想要用户,从哪里user.lastName开始并且仍然可以查询完全匹配怎么办?(?lastName=Xyz,contains和?lastName=Xyz,equals可能)
在QuerydslBinderCustomizer每场的基础上定义了一些操作,但你只能定义如何处理特定领域,有没有可能添加多个操作。
也许我不能用 QueryDSL 做到这一点,但是通常在 Spring Boot 中,您如何将过滤器应用于搜索查询?
我正在做类似的事情。尽管当我尝试执行更复杂的操作时面临一些限制。我在一些步骤中做了什么:
MyBinderCustomizer<T extends EntityPath<?>>扩展的新接口QuerydslBinderCustomizer<QUser>(注意 User 的 Q,您需要 QueryDSL 自动生成的类而不是您的实体)。customize方法。例如:@Override
public default void customize(QuerydslBindings bindings, T root) {
bindings.bind(String.class).all(MyBinderCustomizer::applyStringComparison);
}
static BooleanExpression applyStringComparison(Path<String> path, Collection<? extends String> strings) {
BooleanExpression result = null;
for (String s : strings) {
try {
final String[] parts = s.split(",");
final String operator = parts[0];
final String value = parts.length > 1 ? parts[1] : null;
final Method method = Arrays.stream(path.getClass().getMethods())
.filter(m -> operator.equals(m.getName()))
.filter(m -> BooleanExpression.class.equals(m.getReturnType()))
.filter(m -> m.getParameterTypes().length == (value == null ? 0 : 1))
.filter(m -> value == null || m.getParameterTypes()[0].equals(String.class) || m.getParameterTypes()[0].equals(Object.class))
.findFirst().get();
final BooleanExpression be;
if (value == null) {
be = (BooleanExpression) method.invoke(path);
} else {
be = (BooleanExpression) method.invoke(path, value);
}
result = result == null ? be : result.and(be);
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
MyBinderCustomizer<QUser>(再次注意 Q)。这将让您使用这些操作:
public BooleanExpression StringExpression.like(java.lang.String)
public BooleanExpression StringExpression.notLike(java.lang.String)
public BooleanExpression StringExpression.notEqualsIgnoreCase(java.lang.String)
public BooleanExpression StringExpression.containsIgnoreCase(java.lang.String)
public BooleanExpression StringExpression.likeIgnoreCase(java.lang.String)
public BooleanExpression StringExpression.startsWithIgnoreCase(java.lang.String)
public BooleanExpression StringExpression.endsWithIgnoreCase(java.lang.String)
public BooleanExpression StringExpression.equalsIgnoreCase(java.lang.String)
public BooleanExpression StringExpression.startsWith(java.lang.String)
public BooleanExpression StringExpression.endsWith(java.lang.String)
public BooleanExpression StringExpression.matches(java.lang.String)
public BooleanExpression StringExpression.contains(java.lang.String)
公共布尔表达式 StringExpression.isEmpty()
公共布尔表达式 StringExpression.isNotEmpty()
公共布尔表达式 SimpleExpression.isNull()
公共布尔表达式 SimpleExpression.isNotNull()
公共布尔表达式 SimpleExpression.ne(java.lang.Object)
公共布尔表达式 SimpleExpression.eq(java.lang.Object)
在春季数据QueryDSL值算图书馆延伸春数据QueryDSL网络支持与运营商不仅字符串领域,还数和枚举领域。它需要一些特殊的配置,使其成为非字符串下地干活,为解释在这里:
值运算符在基于字符串的属性/字段上无缝工作。然而,这些运算符不适用于 Number 或 Enum 等非字符串值,因为默认情况下
QuerydslPredicateArgumentResolver解析 annotationQuerydslPredicate,用于注释 RESTful 方法(又名 RestController 方法)上的搜索处理方法,根据指导设计原则执行强类型Querydsl,即它尝试将从 HTTP 请求接收的值转换为相应 Q-Classes 中定义的确切类型。这在没有值运算符的情况下运行良好,并且符合 Querydsl 允许类型安全查询的承诺,但是阻碍了值运算符实现他们的技巧。
该库提供了两种方法来使运算符适用于非字符串字段:
QuerydslPredicateArgumentResolver所有查询参数都被视为字符串(失去强类型)这两种方法都有很好的文档记录,以及它们的用例和缺点。
我目前正在评估方法 1,因为它适合我们的用例,但我需要扩展它以适应 DateTime 字段和一些自定义运算符。
| 归档时间: |
|
| 查看次数: |
5282 次 |
| 最近记录: |