Я написал простой код для запроса 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 class:
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
?