private Specification<VO> createSpecification(final Map<String, String> filterData) throws Exception { final Map<String, String> filterOperators = new HashMap<>(); final Map<String, Object> filterParams = new HashMap(); extractFilterOperatorsAndParams(filterData, filterOperators, filterParams); Specification<VO> spec = new Specification<VO>() { @Override public Predicate toPredicate(Root<VO> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> predicates = new ArrayList<>(); for (Map.Entry<String, Object> entry : filterParams.entrySet()) { //get path to leaf node Path<?> path = root; if(ATTR_JSON_TYPE.equals(entry.getKey())) { predicates.add(root.type().in(entry.getValue())); } else { for (String pk : entry.getKey().split("\\.")) { path = path.get(pk); } // create predicate predicates.add(getFieldPredicate(cb, path, filterOperators.get(entry.getKey()), entry.getValue())); } } return cb.and(predicates.toArray(new Predicate[predicates.size()])); } private Predicate getFieldPredicate(CriteriaBuilder cb, Path<?> path, String operator, Object value) { if (OP_EQUAL.equals(operator)) { if (value instanceof Collection) { return path.in((Collection) value); } return cb.equal(path, value); } else if (OP_NOT.equals(operator)) { if (value instanceof Collection) { List<Predicate> predicates = new ArrayList<>(); for (Object val : (Collection) value) { predicates.add(cb.notEqual(path, val)); } return cb.and(predicates.toArray(new Predicate[predicates.size()])); } else { return cb.notEqual(path, value); } } else if (OP_LIKE.equals(operator)) { return cb.like(path.as(String.class), value.toString()); } else if (OP_NOTLIKE.equals(operator)) { return cb.notLike(path.as(String.class), value.toString()); } else if (OP_BETWEEN.equals(operator)) { Iterator<?> iter = ((Collection<?>) value).iterator(); Object val1 = iter.next(), val2 = iter.next(); if (val1 instanceof Byte) { return cb.between(path.as(Byte.class), (Byte) val1, (Byte) val2); } else if (val1 instanceof Short) { return cb.between(path.as(Short.class), (Short) val1, (Short) val2); } else if (val1 instanceof Integer) { return cb.between(path.as(Integer.class), (Integer) val1, (Integer) val2); } else if (val1 instanceof Long) { return cb.between(path.as(Long.class), (Long) val1, (Long) val2); } else if (val1 instanceof Float) { return cb.between(path.as(Float.class), (Float) val1, (Float) val2); } else if (val1 instanceof Double) { return cb.between(path.as(Double.class), (Double) val1, (Double) val2); } else { return null; } } else { try { Method m = null; if (OP_GT.equals(operator)) { m = cb.getClass().getMethod("greaterThan", Expression.class, Comparable.class); } else if (OP_GE.equals(operator)) { m = cb.getClass().getMethod("greaterThanOrEqualTo", Expression.class, Comparable.class); } else if (OP_LT.equals(operator)) { m = cb.getClass().getMethod("lessThan", Expression.class, Comparable.class); } else if (OP_LE.equals(operator)) { m = cb.getClass().getMethod("lessThanOrEqualTo", Expression.class, Comparable.class); } if (m != null) { if (value instanceof Byte) { return (Predicate) m.invoke(cb, path.as(Byte.class), (Byte) value); } else if (value instanceof Short) { return (Predicate) m.invoke(cb, path.as(Short.class), (Short) value); } else if (value instanceof Integer) { return (Predicate) m.invoke(cb, path.as(Integer.class), (Integer) value); } else if (value instanceof Long) { return (Predicate) m.invoke(cb, path.as(Long.class), (Long) value); } else if (value instanceof Float) { return (Predicate) m.invoke(cb, path.as(Float.class), (Float) value); } else if (value instanceof Double) { return (Predicate) m.invoke(cb, path.as(Double.class), (Double) value); } } } catch (Exception e) { throw new RuntimeException(e); } return null; } } }; return spec; }
Reference:
http://docs.spring.io/spring-data/data-jpa/docs/1.0.x/api/org/springframework/data/jpa/domain/Specification.html
http://docs.oracle.com/javaee/5/api/javax/persistence/package-summary.html
http://wenku.baidu.com/view/190e385c3b3567ec102d8a40.html?re=view
时间: 2024-11-02 23:05:53