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

时间:2018-01-15 11:59:15

标签: java spring querydsl

我在我的一个项目中使用Spring查询DSL。查询DSL谓词是在Controller端点上自动创建的,如此

library(ggnetwork)
library(network)
library(sna)
library(ggnet)

net = rgraph(10, mode = "graph", tprob = 0.5)
net = network(net, directed = FALSE)

network.vertex.names(net) = letters[1:10]

ggnet2(net)

它是通过像这样的查询参数提供的

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

有没有办法从创建的Predicate中提取表达式(path = value)?

我找到了如何从Predicate对象中提取Expression路径,但是我找不到有意义的方法来在这条路径下提取值。

可以像这样提取路径(对于当前示例,它将是person.name)

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

我认为,这应该是通过提取路径的访问者以某种方式完成的,但我无法弄清楚如何。

更新即可。我找到了解决方案:

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

用法非常简单:

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;
    }

   }

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。下面的代码提取表达式的第一个Constant值,它使用它自己的访问者。可以轻松修改解决方案以使用某些常量集合(因为有时在同一路径下有多个值,例如,在日期范围内)

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;
    }

   }

用法:

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);
}