Spring QueryDSL动态谓词

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<

我需要有关QueryDSL查询的帮助。我将这个库与Spring数据JPA一起使用。 我的服务级别:

@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(...)