Spring QueryDSL动态谓词
我需要有关QueryDSL查询的帮助。我将这个库与Spring数据JPA一起使用。 我的服务级别:Spring QueryDSL动态谓词,spring,spring-data-jpa,querydsl,Spring,Spring Data Jpa,Querydsl,我需要有关QueryDSL查询的帮助。我将这个库与Spring数据JPA一起使用。 我的服务级别: @Service("tblActivityService") public class TblActivityService implements AbstractService<TblActivity> { @Resource private TblActivityRepository tblActivityRepository; @Override public List<
@Service("tblActivityService")
public class TblActivityService implements AbstractService<TblActivity> {
@Resource
private TblActivityRepository tblActivityRepository;
@Override
public List<TblActivity> findAll(Predicate predicate) {
return (List<TblActivity>) tblActivityRepository.findAll(predicate);
}
}
我有列名(例如标题)
我有条件(例如==,!=,>=等)-我可以将其存储为符号或单词(等于等)
最后,我有了价值
问题是“如何为我的服务动态生成谓词?”
表中有大约25个字段
谓词如下所示:
public BooleanExpression buildFilteredResult(List<SysFilter> filters) {
//TODO do it!
return QTblActivity.tblActivity.title.eq("Value");
// I need to do it dynamically for each filter in the list
}
公共布尔表达式buildFilteredResult(列表过滤器){
//去做吧!
返回QTblActivity.tblActivity.title.eq(“值”);
//我需要为列表中的每个过滤器动态执行此操作
}
问题是如何通过其字符串值调用columnName。
你有什么建议吗?我找到了解决方案:
public BooleanExpression buildFilteredResult(List<SysFilter> filters) {
//TODO do it!
QTblActivity qTblActivity = QTblActivity.tblActivity;
BooleanExpression expression = qTblActivity.recordState;
for (SysFilter filter : filters) {
StringPath stringPath = new StringPath(qTblActivity, filter.getColumnName());
switch (filter.getCondition()) {
case "==":
expression.and(stringPath.eq(filter.getValue()));
break;
case "!=":
expression.and(stringPath.ne(filter.getValue()));
break;
case ">":
expression.and(stringPath.gt(filter.getValue()));
break;
case "<":
expression.and(stringPath.lt(filter.getValue()));
break;
case ">=":
expression.and(stringPath.goe(filter.getValue()));
break;
case "<=":
expression.and(stringPath.loe(filter.getValue()));
break;
default:
break;
}
}
return expression;
}
公共布尔表达式buildFilteredResult(列表过滤器){
//去做吧!
QTblActivity QTblActivity=QTblActivity.tblActivity;
BooleanExpression=qTblActivity.recordState;
for(SysFilter过滤器:过滤器){
StringPath StringPath=newStringPath(qTblActivity,filter.getColumnName());
开关(filter.getCondition()){
案例“==”:
表达式和(stringPath.eq(filter.getValue());
打破
案例“!=”:
表达式和(stringPath.ne(filter.getValue());
打破
案例“>”:
表达式和(stringPath.gt(filter.getValue());
打破
案例“=”:
表达式和(stringPath.goe(filter.getValue());
打破
case“使用将筛选条件映射到运算符可能更容易
Map<String, Operator> operators = ImmutableMap.of(
"==", Ops.EQ, "!=", Ops.NE, ">", Ops.GT, "<", Ops.LT,
">=", Ops.GOE, "<=", Ops.LOE);
Expressions.predicate(operators.get(condition),
stringPath, Expressions.constant(filterValue));
返回一个新谓词,并保持谓词
不变
也许你想要的是
BooleanBuilder
?一个新的解决方案是用spring data Gosling/Fowler发布的。如果你正在创建一个web应用程序,你可以使用querydsl web支持为你做这项工作-它将get参数读入一个谓词,然后你可以从你的控制器使用这个谓词-无需手动这样做-
您可以根据特定数据类型或特定实体字段所需的搜索条件(相等,如…)自定义存储库。
提供列名作为字符串值违背了Querydsl的目的。Querydsl背后的思想是,您不需要列名作为字符串,而是以编译安全和类型安全的方式引用它们。嗯,我不想为所有可能的变体编写代码(这将是大量代码).是否有任何方法可以动态插入列名?或者可能有其他方法可以在没有QueryDSL的情况下实现我的需求?如果属性是NumberPath,如何实现?
Map<String, Operator> operators = ImmutableMap.of(
"==", Ops.EQ, "!=", Ops.NE, ">", Ops.GT, "<", Ops.LT,
">=", Ops.GOE, "<=", Ops.LOE);
Expressions.predicate(operators.get(condition),
stringPath, Expressions.constant(filterValue));
predicates.and(...)