如何从 Spring 查询 dsl 谓词中提取表达式路径和值?
How to extract expression path and value from Spring query dsl Predicate?
我在我的一个项目中使用 Spring 查询 DSL。查询 DSL 谓词是在 Controller 端点上自动创建的,就像这样
public ResponseEntity<MyDTO> agentWinLoseSA(
@QuerydslPredicate(root = MyObject.class) Predicate filter, Pageable pageable) throws URISyntaxException
它是通过这样的查询参数提供的
https://myhost:port/api/myobj?person.name=Dave
有没有办法从创建的谓词中提取表达式(路径=值)?
我找到了如何从 Predicate 对象中提取表达式路径,但我找不到有意义的方法来提取该路径下的值。
路径可以像这样提取(对于当前示例,它将是 person.name)
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;
}
}
用法很简单:
Constant constant = expression.accept(ConstantExtractor.DEFAULT, null);
我找到了解决方案。下面的代码首先提取表达式的常量值,它使用它自己的访问者。可以轻松修改解决方案以使用一些常量集合(因为有时同一路径下有多个值,例如,在日期范围内)
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);
}
我在我的一个项目中使用 Spring 查询 DSL。查询 DSL 谓词是在 Controller 端点上自动创建的,就像这样
public ResponseEntity<MyDTO> agentWinLoseSA(
@QuerydslPredicate(root = MyObject.class) Predicate filter, Pageable pageable) throws URISyntaxException
它是通过这样的查询参数提供的
https://myhost:port/api/myobj?person.name=Dave
有没有办法从创建的谓词中提取表达式(路径=值)?
我找到了如何从 Predicate 对象中提取表达式路径,但我找不到有意义的方法来提取该路径下的值。
路径可以像这样提取(对于当前示例,它将是 person.name)
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;
}
}
用法很简单:
Constant constant = expression.accept(ConstantExtractor.DEFAULT, null);
我找到了解决方案。下面的代码首先提取表达式的常量值,它使用它自己的访问者。可以轻松修改解决方案以使用一些常量集合(因为有时同一路径下有多个值,例如,在日期范围内)
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);
}