spring jpa 动态查询(Specification)

//dao层  继承 扩展仓库接口JpaSpecificationExecutor   (JPA 2引入了一个标准的API
public
interface CreditsEventDao extends JpaRepository<CreditsEventBean, Integer>, JpaSpecificationExecutor<CreditsEventBean>{}

 https://docs.spring.io/spring-data/jpa/docs/current/reference/html/      官方文档 -- 5.5. Specifications

JpaSpecificationExecutor提供了以下接口:

/**
 * Interface to allow execution of {@link Specification}s based on the JPA criteria API.
 * 
 * @author Oliver Gierke
 */
public interface JpaSpecificationExecutor<T> {

    /**
     * Returns a single entity matching the given {@link Specification}.
     * 返回与给定的{@link规范}匹配的单个实体
     * @param spec
     * @return
     */
    T findOne(Specification<T> spec);

    /**
     * Returns all entities matching the given {@link Specification}.
     * 返回与给定的{@link规范}匹配的所有实体。
     * @param spec
     * @return
     */
    List<T> findAll(Specification<T> spec);

    /**
     * Returns a {@link Page} of entities matching the given {@link Specification}.
     * 返回与给定的{@link规范}匹配的实体的{@link页面}。
     * @param spec
     * @param pageable
     * @return
     */
    Page<T> findAll(Specification<T> spec, Pageable pageable);

    /**
     * Returns all entities matching the given {@link Specification} and {@link Sort}.
     * 返回与给定的{@link规范}和{@link排序}匹配的所有实体。
     * @param spec
     * @param sort
     * @return
     */
    List<T> findAll(Specification<T> spec, Sort sort);

    /**
     * Returns the number of instances that the given {@link Specification} will return.
     * 返回给定的{@link规范}将返回的实例数量。
     * @param spec the {@link Specification} to count instances for
     * @return the number of instances
     */
    long count(Specification<T> spec);
}
  

我项目上使用到的实例:

public Page<TestBean> specificationFind(Integer size, Integer page, TestBean test) {
        Field[] fields = CreditsEventBean.class.getDeclaredFields(); //通过反射获取实体类的所有属性
        Sort sort = new Sort(Direction.ASC, "sort").and(new Sort(Direction.DESC, "cutOffTime"));//排序规则   多条件
        Pageable pageable = new PageRequest(page-1, size, sort);//分页
        return activityDao.findAll(new Specification<CreditsEventBean>() {// Page<T> findAll(Specification<T> spec, Pageable pageable);  分页加多态查询  
            @SuppressWarnings("unchecked")//压制警告
            @Overridepublic Predicate toPredicate(Root<CreditsEventBean> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Map<String, Object> conditions = null;
                try {
                    conditions = BeanUtils.describe(event);//使用Apache的工具类将实体转换成map
                    conditions.remove("sort");//去掉某些用不到的字段  比如排序字段等
                    conditions.remove("maxPlayers");//                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    e.printStackTrace();
                    System.err.println("specificationFind ---bean转map出错");
                }
                List<Predicate> predicates = new ArrayList<>();//存储查询语句
                for (int i = 0; i < fields.length; i++) {//循环bean的所有属性
                    fields[i].setAccessible(true);//是否允许访问
                    String name = fields[i].getName();//获取属性名
                    if(conditions.containsKey(name)) {//查询这个键是否存在与这个属性中
                        if(ObjectUtils.isEmpty(conditions.get(name))) {//判断这个键的值是否为空
                            continue;//结束本次循环,进入下一次循环
                        }
                        if(name.equals("creditStatus")||name.equals("activityShop")
                                ||name.equals("isShopEvent")||name.equals("isPutaway")) {//这里  等于条件
                            predicates.add(cb.equal(root.get(name), conditions.get(name)));
                            continue;
                        }else if(name.equals("activityStartCreditsDT")||name.equals("activityEndCreditsDT")
                                ||name.equals("creteateTime")||name.equals("cutOffTime")) {// 这里是between条件
                            String value = (String) conditions.get(name);
                            String[] split = value.split(",");//分割
                            predicates.add(cb.between(root.get(name), split[0], split[1]));
                            continue;
    
                        }
                        predicates.add(cb.like(root.get(name), "%"+conditions.get(name)+"%"));// 这里是 模糊 条件          
                    }
                }
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));//返回结果集
            }
        }, pageable);
        
        
        
    }

 CriteriaBuilder主要api:

等!

猜你喜欢

转载自www.cnblogs.com/tanning/p/10097098.html