QueryDSL 动态谓词
QueryDSL dynamic predicates
我需要有关 QueryDSL 查询的帮助。我将此库与 Spring Data JPA 一起使用。
我的服务 class:
@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);
}
}
我有过滤器的动态列表:
@Entity
@Table(name = "sys_filters")
public class SysFilter implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "filter_id")
private Integer filterId;
@JoinColumn(name = "user_id", referencedColumnName = "user_id")
@ManyToOne(fetch = FetchType.EAGER)
private SysUser userId;
@Size(max = 45)
@Column(name = "table_name")
private String tableName;
@Size(max = 45)
@Column(name = "column_name")
private String columnName;
@Size(max = 45)
@Column(name = "condition")
private String condition;
@Size(max = 100)
@Column(name = "value")
private String value;
// getters & setters
}
我有列名(例如标题)
我有条件(例如 ==、!=、>= 等)- 我可以将其存储为符号或单词(等于等)
我终于有价值了。
问题是"how to dynamically generate predicate for my service?"
Table 大约有 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
}
问题是如何通过字符串值调用 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;
}
使用映射过滤条件到运算符可能更容易
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(...)
returns 一个新谓词并保持 predicates
不变。
也许 BooleanBuilder
就是您想要的?
更新的解决方案已发布,其中包含 spring 数据 Gosling/Fowler。如果您正在创建一个网络应用程序,您可以使用为您完成工作的 querydsl 网络支持 - 它将获取参数读入谓词,然后您可以从您的控制器使用这个谓词 - 无需手动执行 -
您可以根据特定数据类型或特定实体字段所需的搜索条件(等于,如...)自定义您的存储库。
see the documentation here
我需要有关 QueryDSL 查询的帮助。我将此库与 Spring Data JPA 一起使用。 我的服务 class:
@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);
}
}
我有过滤器的动态列表:
@Entity
@Table(name = "sys_filters")
public class SysFilter implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "filter_id")
private Integer filterId;
@JoinColumn(name = "user_id", referencedColumnName = "user_id")
@ManyToOne(fetch = FetchType.EAGER)
private SysUser userId;
@Size(max = 45)
@Column(name = "table_name")
private String tableName;
@Size(max = 45)
@Column(name = "column_name")
private String columnName;
@Size(max = 45)
@Column(name = "condition")
private String condition;
@Size(max = 100)
@Column(name = "value")
private String value;
// getters & setters
}
我有列名(例如标题) 我有条件(例如 ==、!=、>= 等)- 我可以将其存储为符号或单词(等于等) 我终于有价值了。
问题是"how to dynamically generate predicate for my service?" Table 大约有 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
}
问题是如何通过字符串值调用 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;
}
使用映射过滤条件到运算符可能更容易
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(...)
returns 一个新谓词并保持 predicates
不变。
也许 BooleanBuilder
就是您想要的?
更新的解决方案已发布,其中包含 spring 数据 Gosling/Fowler。如果您正在创建一个网络应用程序,您可以使用为您完成工作的 querydsl 网络支持 - 它将获取参数读入谓词,然后您可以从您的控制器使用这个谓词 - 无需手动执行 - 您可以根据特定数据类型或特定实体字段所需的搜索条件(等于,如...)自定义您的存储库。 see the documentation here