Spring Data JPA Specification Query

谁都会走 提交于 2020-03-05 05:35:21
 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!