如何使用带有2个或更多实体的Criteria Builder进行过滤

时间:2019-03-28 15:23:51

标签: java hibernate-criteria

我具有过滤数据的功能。 当我使用1实体时,下面给出的此功能可以正常工作,但是现在 我需要创建过滤器,以便能够从多个实体中过滤-以及 我事先不知道哪个实体 我将不得不过滤(取决于最终用户在网站上输入的条件)

Example Input

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;
        }
    }

0 个答案:

没有答案