Spring Data JPA Specification Query

 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-08-29 12:44:21

Spring Data JPA Specification Query的相关文章

Spring data jpa中Query和@Query分别返回map结果集

引用: http://blog.csdn.net/yingxiake/article/details/51016234 http://blog.csdn.net/yingxiake/article/details/51016234 http://www.cnblogs.com/zj0208/p/6008627.html Query的使用: 在JPA 2.0 中我们可以使用entityManager.createNativeQuery()来执行原生的SQL语句. 但当我们查询结果没有对应实体类时,

Spring Data JPA native query 分页

Mysql Spring Data JPA and native queries with pagination Spring Data and Native Query with pagination public interface UserRepository extends JpaRepository<User, Long> { @Query(value = "select * from users order by id desc \n#pageable\n",

spring data jpa Specification 复杂查询+分页查询

当Repository接口继承了JpaSpecificationExecutor后,我们就可以使用如下接口进行分页查询: /** * Returns a {@link Page} of entities matching the given {@link Specification}. * * @param spec can be {@literal null}. * @param pageable must not be {@literal null}. * @return never {@l

Spring data jpa Specification查询关于日期的范围搜索

代码: 时间格式化类型: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat sdfmat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) { pr

Spring data jpa @OneToMany 在一的一端进行查询()对集合属性设置条件查询)

业务场景: 一个商品对应多个仓存,需要查询商品在某个或某几个库存中存在时,查询出来. 实体类 ,商品Goods @Entity @Table(name = "es_goods") public class Goods { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "goods_id") private Integer id; private String name; //

Spring data jpa 实现简单动态查询的通用Specification方法

本篇前提: SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法 这篇文章中的第二种方法 实现Specification 这块的方法 只适用于一个对象针对某一个固定字段查询,下面通过泛型改写了这个方法: import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import j

深入浅出学Spring Data JPA toPredicate Predicate[] p = new Predicate[list.size()]; query.where(cb.and

序言自工作以来,除了以前比较流量的hibernate,就是一直使用ORM 规范 JPA了.而这几天工作需要,研究了下JPA的标准查询,名为:JPA criteria查询.相比JPQL,其优势是类型安全,更加的面向对象.使用标准查询,开发人员可在编译的时候就检查查询的正确与否.而以前也只是在Hibernate中听说有过.具体不详,没用过.JPA元模型概念,及使用在JPA中,标准查询是以元模型的概念为基础的.元模型是为具体持久化单元的受管实体定义的.这些实体可以是实体类,嵌入类或者映射的父类.提供受

spring data jpa封装specification实现简单风格的动态查询

github:https://github.com/peterowang/spring-data-jpa-demo Spring Data JPA已经帮助我们很大程度上简化了我们的查询操作,我们甚至只要写一个接口,然后单纯的写一些方法就可以完成各式各样的查询,但是对于我们程序设计人员而言,总希望所有的查询变得更加的简单方便,为了给程序人员进行再一次的封装,Spring Data JPA提供了Specification的方式进行查询,在前面的内容已经演示过这种查询了,但是,我们在使用的过程中发现这

Spring Data JPA进阶——Specifications和Querydsl

Spring Data JPA进阶--Specifications和Querydsl 本篇介绍一下Spring Data JPA中能为数据访问程序的开发带来更多便利的特性,我们知道,Spring Data repository的配置很简单,一个典型的repository像下面这样: public interface CustomerRepository extends JpaRepository<Customer, Long> { Customer findByEmailAddress(Str