简体   繁体   English

如何从Spring查询dsl谓词中提取表达式的路径和值?

[英]How to extract expression path and value from Spring query dsl Predicate?

I'm using Spring query DSL on one of my projects. 我在一个项目上使用Spring查询DSL。 Query DSL predicates are created automatically on Controller endpoint, like this 查询DSL谓词是在Controller端点上自动创建的,如下所示

public ResponseEntity<MyDTO> agentWinLoseSA(
        @QuerydslPredicate(root = MyObject.class) Predicate filter, Pageable pageable) throws URISyntaxException

It is supplied via query params like this 它是通过这样的查询参数提供的

https://myhost:port/api/myobj?person.name=Dave

Is there any way to extract expressions (path=value) from created Predicate? 有什么方法可以从创建的谓词中提取表达式(path = value)?

I found how to extract Expression path from Predicate object, but I can't find meaningful way to extract value under this path. 我找到了如何从谓词对象中提取表达式路径的方法,但找不到在该路径下提取值的有意义的方法。

Path can be extracted like this (and for current example it will be person.name) 可以这样提取路径(在当前示例中为person.name)

    List<Expression<?>> expressions = ((PredicateOperation) filter).getArgs();
    for (Expression<?> expression : expressions)
    {
        String expressionPath = expression.accept(PathExtractor.DEFAULT, null).toString();
    }

I assume, this is somehow should be done via visitors with extracted path, but I can't figure out how. 我认为,这应该通过提取路径的访问者来完成,但是我不知道如何做到。

UPDATE . 更新 I found a solution: 我找到了解决方案:

import com.querydsl.core.types.Constant;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.FactoryExpression;
import com.querydsl.core.types.Operation;
import com.querydsl.core.types.ParamExpression;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.SubQueryExpression;
import com.querydsl.core.types.TemplateExpression;
import com.querydsl.core.types.Visitor;


public class ConstantExtractor implements Visitor<Constant<?>, Void>
{

    public static final ConstantExtractor DEFAULT = new ConstantExtractor();


    private ConstantExtractor()
    {
    }


    @Override
    public Constant<?> visit(Constant<?> expr, Void context)
    {
        return expr;
    }


    @Override
    public Constant<?> visit(FactoryExpression<?> expr, Void context)
    {
        return visit(expr.getArgs());
    }


    @Override
    public Constant<?> visit(Operation<?> expr, Void context)
    {
        return visit(expr.getArgs());
    }


    @Override
    public Constant<?> visit(ParamExpression<?> expr, Void context)
    {
        return null;
    }


    @Override
    public Constant<?> visit(Path<?> expr, Void context)
    {
        return null;
    }


    @Override
    public Constant<?> visit(SubQueryExpression<?> expr, Void context)
    {
        return null;
    }


    @Override
    public Constant<?> visit(TemplateExpression<?> expr, Void context)
    {
        return visit(expr.getArgs());
    }


    private Constant<?> visit(List<?> exprs)
    {
        for (Object e : exprs)
        {
            if (e instanceof Expression)
            {
                Constant<?> constant = ((Expression<?>) e).accept(this, null);
                if (constant != null)
                {
                    return constant;
                }
            }
        }

        return null;
    }

   }

Usage is quite simple: 用法很简单:

Constant constant = expression.accept(ConstantExtractor.DEFAULT, null);

I found a solution . 我找到了解决方案 Code below extracts first Constant value of expression, it uses it own visitor. 下面的代码首先提取表达式的Constant值,它使用它自己的访问者。 Solution can be easily modified to work with some collection of Constants (because sometimes there are more then one value under the same path, for example, in date ranges) 可以轻松修改解决方案以与某些常量集合一起使用(因为有时在同一路径下(例如,在日期范围内)会有一个以上的值)

import com.querydsl.core.types.Constant;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.FactoryExpression;
import com.querydsl.core.types.Operation;
import com.querydsl.core.types.ParamExpression;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.SubQueryExpression;
import com.querydsl.core.types.TemplateExpression;
import com.querydsl.core.types.Visitor;


public class ConstantExtractor implements Visitor<Constant<?>, Void>
{

    public static final ConstantExtractor DEFAULT = new ConstantExtractor();


    private ConstantExtractor()
    {
    }


    @Override
    public Constant<?> visit(Constant<?> expr, Void context)
    {
        return expr;
    }


    @Override
    public Constant<?> visit(FactoryExpression<?> expr, Void context)
    {
        return visit(expr.getArgs());
    }


    @Override
    public Constant<?> visit(Operation<?> expr, Void context)
    {
        return visit(expr.getArgs());
    }


    @Override
    public Constant<?> visit(ParamExpression<?> expr, Void context)
    {
        return null;
    }


    @Override
    public Constant<?> visit(Path<?> expr, Void context)
    {
        return null;
    }


    @Override
    public Constant<?> visit(SubQueryExpression<?> expr, Void context)
    {
        return null;
    }


    @Override
    public Constant<?> visit(TemplateExpression<?> expr, Void context)
    {
        return visit(expr.getArgs());
    }


    private Constant<?> visit(List<?> exprs)
    {
        for (Object e : exprs)
        {
            if (e instanceof Expression)
            {
                Constant<?> constant = ((Expression<?>) e).accept(this, null);
                if (constant != null)
                {
                    return constant;
                }
            }
        }

        return null;
    }

   }

And usage: 和用法:

List<Expression<?>> expressions = ((PredicateOperation) filter).getArgs();
for (Expression<?> expression : expressions)
{
    String expressionPath = expression.accept(PathExtractor.DEFAULT, null).toString();
    Constant constant = expression.accept(ConstantExtractor.DEFAULT, null);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM