@SuppressWarnings("unchecked") public Predicate getCanReadOrgPredicate( User user, OrgType type, CriteriaBuilder cb, CriteriaQuery<Organization> query, boolean containRoot) { // 一。获得可管理的顶层机构,不区分机构类型 List<Organization> topCanReadOrgs = getTopCanReadOrgs(user); Root<Organization> from; if (query.getRoots().size() > 0) { from = (Root<Organization>) query.getRoots().iterator().next(); } else { from = query.from(Organization.class); } if (topCanReadOrgs.size() == 0) { return cb.isNull(from); } // 二。应用条件 // 1.机构范围限制(如果有全部数据权限不做限制) Subquery<Organization> subquery = query.subquery(Organization.class); Root<Organization> subfrom = subquery.from(Organization.class); subquery.select(subfrom); ListJoin<Organization, Organization> join = subfrom.join(Organization_.ancestors, JoinType.INNER); In<String> subin = cb.in(join.get(Organization_.id)); for (Organization o : topCanReadOrgs) { subin = subin.value(o.getId()); } // 2.应用机构类别 if (type != null) { Predicate p = cb.equal(subfrom.get(Organization_.orgType), type); subquery.where(cb.and(subin, p)); } else { subquery.where(subin); } // 3.增加祖先节点 if (containRoot) { In<String> in = cb.in(from.get(Organization_.id)); boolean hasdata = false; for (Organization o : topCanReadOrgs) { Organization parento = o.getParent(); while (parento != null) { hasdata = true; in = in.value(parento.getId()); parento = parento.getParent(); } } if (hasdata) { return cb.or(cb.in(from).value(subquery), in); } } return cb.in(from).value(subquery); }
/** * Creates and returns an "in" disjunction (i.e. an "or statement") using the arguments provided. * The returned disjunction is semantically similar to: "<code>propertyName</code> in <code> * expressionList</code>", but works around the Oracle expression list size limit. </br></br> See: * "ORA-01795: maximum number of expressions in a list is 1000" * * @param expressionList The expression list for the statement. * @param property The property to check with the statement. * @param criteriaBuilder The builder to use to construct the disjunction. * @return the created disjunction. */ @SuppressWarnings({"rawtypes", "unchecked"}) public static Predicate getExpressionDisjunction( Collection expressionList, Path property, CriteriaBuilder criteriaBuilder) { List<Predicate> expressionCollections = new ArrayList<Predicate>(); In currentSet = criteriaBuilder.in(property); int count = MAX_DB_VALUE_LIST; for (Object expression : expressionList) { if (count >= MAX_DB_VALUE_LIST) { currentSet = criteriaBuilder.in(property); expressionCollections.add(currentSet); count = 0; } currentSet.value(expression); count++; } return criteriaBuilder.or( expressionCollections.toArray(new Predicate[expressionCollections.size()])); }