我已经编写了简单的代码来查询具有多个(可选)参数的JPA
,就像这样:
@Getter
@Setter
public class SearchCriteria {
private String key;
private Object value;
private SearchOperation operation;
public SearchCriteria(String key, Object value, SearchOperation operation) {
this.key = key;
this.value = value;
this.operation = operation;
}
}
SearchOption类:
public enum SearchOperation {
GREATER_THAN,
LESS_THAN,
GREATER_THAN_EQUAL,
LESS_THAN_EQUAL,
NOT_EQUAL,
EQUAL,
MATCH,
MATCH_END,
BETWEEN_DATE,
GREATER_THAN_DATE,
LESS_THAN_DATE;
}
还有一个GenericSpecification类:
public class GenericSpecification<T> implements Specification<T> {
private SimpleDateFormat localeIta = new SimpleDateFormat("dd/MM/yyyy");
private List<SearchCriteria> list;
public GenericSpecification() {
this.list = new ArrayList<>();
}
public void add(SearchCriteria criteria) {
list.add(criteria);
}
@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
List<Predicate> predicates = new ArrayList<>();
for (SearchCriteria criteria : list) {
switch(criteria.getOperation()) {
....
case BETWEEN_DATE: {
Path<Date> entityDate = root.get(criteria.getKey());
predicates.add(builder.between(entityDate, getComparingDates((String[])criteria.getValue(), 0), getComparingDates((String[])criteria.getValue(), 1)));
}
break;
}
return builder.and(predicates.toArray(new Predicate[0]));
}
这是用于带有参数的构建查询,即使它们被价目化,例如:
GenericSpecification spec = new GenericSpecification<CreditCard>:
If (param != null) spec.add(new SearchCriteria("fieldName", param, SearchOperation.OPE));
如果设置了某些参数,现在我必须联接几个表。使用metamodel
或Specification
执行联接的最佳方法是什么?