我具有过滤数据的功能。 当我使用1实体时,下面给出的此功能可以正常工作,但是现在 我需要创建过滤器,以便能够从多个实体中过滤-以及 我事先不知道哪个实体 我将不得不过滤(取决于最终用户在网站上输入的条件)
public PaginationResult getFilteredData(List<FilterConstraint> filters, Object className) {
if (filters.get(0).getCount() == 0) {
filters.get(0).setCount(50);
}
try {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<?> mainQuery = builder.createQuery(className.getClass());
Root<?> root = mainQuery.from(className.getClass());
Predicate predicate = builder.conjunction();
Predicate enumPredicate = builder.conjunction();
Predicate in = builder.conjunction();
Predicate range = builder.conjunction();
Predicate after = builder.conjunction();
Predicate before = builder.conjunction();
Predicate between = builder.conjunction();
Predicate empty = builder.conjunction();
Predicate equals = builder.conjunction();
Predicate lessThen = builder.conjunction();
Predicate moreThen = builder.conjunction();
Predicate notEmpty = builder.conjunction();
Predicate today = builder.conjunction();
Predicate on = builder.conjunction();
for (FilterConstraint constraint: filters) {
switch (constraint.getOperator()) {
case IN:
LocalDate inDate = new LocalDate();
Date maxRange = inDate.plusDays(Integer.parseInt(constraint.getValues().getMinValue())).toDate();
in = builder.and(builder.between(root.get(constraint.getField().getValue()), inDate.toDate(), maxRange));
break;
case RANGE:
LocalDate rangeDate = new LocalDate();
Date minDate = rangeDate.plusDays(Integer.parseInt(constraint.getValues().getMinValue())).toDate();
Date maxDate = rangeDate.plusDays(Integer.parseInt(constraint.getValues().getMaxValue())).toDate();
range = builder.and(builder.between(root.get(constraint.getField().getValue()), minDate, maxDate));
break;
case AFTER:
after = builder.and(builder.greaterThan(root.get(constraint.getField().getValue()), constraint.getValues().getStartDate()));
break;
case BEFORE:
before = builder.and(builder.lessThan(root.get(constraint.getField().getValue()), constraint.getValues().getStartDate()));
break;
case BETWEEN:
if (constraint.getField().getType() == FieldDataType.DATE) {
between = builder.and(builder.between(root.get(constraint.getField().getValue()), constraint.getValues().getStartDate(), constraint.getValues().getEndDate()));
} else if (constraint.getField().getType() == FieldDataType.INTEGER) {
between = builder.and(builder.between(root.get(constraint.getField().getValue()), Integer.valueOf(constraint.getValues().getMinValue()), Integer.valueOf(constraint.getValues().getMaxValue())));
} else {
between = builder.and(builder.between(root.get(constraint.getField().getValue()), constraint.getValues().getMinValue(), constraint.getValues().getMaxValue()));
}
break;
case EMPTY:
empty = builder.and(builder.isEmpty(root.get(constraint.getField().getValue())));
break;
case EQUALS:
if (constraint.getField().getType() == FieldDataType.ENUM) {
Object enumV = null;
if (constraint.getValues().getEnumValue().size() > 1) {
List<Predicate> predicates = new ArrayList<>();
for (EnumValue enumValue : constraint.getValues().getEnumValue()) {
for (Field f : className.getClass().getDeclaredFields()) {
if (f.getName().equals(constraint.getField().getValue())) {
System.out.println("T");
Class<?> clz = f.getType();
Object[] consts = clz.getEnumConstants();
for (int i = 0; i < consts.length - 1; i++) {
if (consts[i].toString().equals(enumValue.getValue())) {
enumV = consts[i];
break;
}
}
}
}
predicates.add(builder.equal(root.get(constraint.getField().getValue()), enumV));
}
enumPredicate = builder.and(builder.or(predicates.toArray(new Predicate[]{})));
break;
}
for (Field f : className.getClass().getDeclaredFields()) {
if (f.getName().equals(constraint.getField().getValue())) {
System.out.println("T");
Class<?> clz = f.getType();
Object[] consts = clz.getEnumConstants();
for (int i = 0; i < consts.length ; i++) {
if (consts[i].toString().equals(constraint.getValues().getEnumValue().get(0).getValue())) {
enumV = consts[i];
break;
}
}
}
}
enumPredicate = builder.equal(root.get(constraint.getField().getValue()), enumV);
break;
}
equals = builder.and(builder.equal(root.get(constraint.getField().getValue()), constraint.getValues().getValue()));
break;
case LESS_THAN:
lessThen = builder.and(builder.lessThan(root.get(constraint.getField().getValue()), constraint.getValues().getValue()));
break;
case MORE_THAN:
//predicate = builder.and(builder.greaterThan(root.get(constraint.getField().getValue()), constraint.getValues().getValue()));
moreThen = builder.and(builder.greaterThan(root.get(constraint.getField().getValue()), constraint.getValues().getValue()));
break;
case NOT_EMPTY:
notEmpty = builder.and(builder.isNotEmpty(root.get(constraint.getField().getValue())));
break;
case ON:
on = builder.between(root.get(constraint.getField().getValue()), DateUtils.getFirstSecondOfDate(constraint.getValues().getStartDate()), DateUtils.getLastSecondOfDate(constraint.getValues().getStartDate()));
break;
/*case STARTS_WITH:*/
case TODAY:
today = builder.and(builder.between(root.get(constraint.getField().getValue()), DateUtils.getFirstSecondOfDate(new Date()), DateUtils.getLastSecondOfDate(new Date())));
break;
}
}
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
cq.select(builder.count(cq.from(className.getClass())));
em.createQuery(cq);
cq.where(predicate, enumPredicate, today, on, moreThen, after, in, range, before, between, empty, equals, lessThen, notEmpty);
Long count = em.createQuery(cq).getSingleResult();
mainQuery.where(predicate, enumPredicate, today, on, moreThen, after, in, range, before, between, empty, equals, lessThen, notEmpty);
//TODO Pagination Result should be returned
TypedQuery<?> q = em.createQuery(mainQuery);
q.setMaxResults(filters.get(0).getCount());
int firstResult = filters.get(0).getPage() * filters.get(0).getCount() - filters.get(0).getCount();
q.setFirstResult(firstResult);
PaginationResult result = new PaginationResult();
result.setData(q.getResultList());
result.setMaxResults(count);
System.out.println(result.getData().size());
return result;
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}