封装JpaSpecificationExecutor简化多条件查询

一、JpaSpecificationExecutor原生查询及其概述

1.1 概述

Spring Data JPA为我们提供了一系列的接口比如:Repository、CrudRepository、PagingAndSortingRepository、JpaRepository、JPASpecificationExecutor等。我们只需要继承这些接口就可以很方便的对数据库进行操作。但是当我们运用JPASpecificationExecutor接口进行一些比较复杂的条件查询的时候,就会显得有点麻烦,下面先来个查询的demo体验一下:

1.2 原生条件查询

我们假设usersRepositorySpecification已经继承了相关接口,以name和age为条件进行查询:
/**	
 * JpaSpecificationExecutor   多条件测试
 */
@Test
public void testJpaSpecificationExecutor2() {
	
    /**
     * Specification<Users>:用于封装查询条件
     */
    Specification<Users> spec = new Specification<Users>() {
	
        //Predicate:封装了 单个的查询条件
        /**
         * Root<Users> root:查询对象的属性的封装。
         * CriteriaQuery<?> query:封装了我们要执行的查询中的各个部分的信息,select  from order by
         * CriteriaBuilder cb:查询条件的构造器。定义不同的查询条件
         */
        @Override
        public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            List<Predicate> list = new ArrayList<>();
            list.add(cb.equal(root.get("name"),"张三三"));
            list.add(cb.equal(root.get("age"),20));
            Predicate[] arr = new Predicate[list.size()];
            return cb.and(list.toArray(arr));
        }
    };
    List<Users> list = this.usersRepositorySpecification.findAll(spec);
    for (Users users : list) {
        System.out.println(users);
    }
}

二、对上述查询进行封装简化

  1. QueryWraper类,包装用于构建JPA动态查询时所需的对象

     public class QueryWraper<T> {
    
     	public QueryWraper(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb, List<Predicate> predicates) {
     		this.root = root;
     		this.query = query;
     		this.cb = cb;
     		this.predicates = predicates;
     	}
     
     	/**
     	 * JPA Root
     	 */
     	private Root<T> root;
     	/**
     	 * JPA CriteriaBuilder
     	 */
     	private CriteriaBuilder cb;
     	/**
     	 * JPA Predicate 集合
     	 */
     	private List<Predicate> predicates;
     	/**
     	 * JPA 查询对象
     	 */
     	private CriteriaQuery<?> query;
     
     	/**
     	 * <pre>
     	 *		增加查询条件
     	 * <pre>
     	 * @param predicate
     	 * @author jojo 2014-8-12 下午3:12:36
     	 */
     	public void addPredicate(Predicate predicate) {
     		this.predicates.add(predicate);
     	}
    
     	public Root<T> getRoot() {
     		return root;
     	}
     
     	public void setRoot(Root<T> root) {
     		this.root = root;
     	}
     
     	public CriteriaBuilder getCb() {
     		return cb;
     	}
     
     	public void setCb(CriteriaBuilder cb) {
     		this.cb = cb;
     	}
     
     	public List<Predicate> getPredicates() {
     		return predicates;
     	}
     
     	public void setPredicates(List<Predicate> predicates) {
     		this.predicates = predicates;
     	}
     
     	public CriteriaQuery<?> getQuery() {
     		return query;
     	}
     	
     	public void setQuery(CriteriaQuery<?> query) {
     		this.query = query;
     	}
     
     }
    
  2. AbstractConditionBuilder抽象类,提供比如:in条件、between条件、like条件等一系列复杂查询条件

     public abstract class AbstractConditionBuilder<T> {
    
     /**
      * 添加in条件
      * @param queryWraper
      * @param column  哪个属性
      * @param values  在(in)哪些值里面
      */
     protected void addInConditionToColumn(QueryWraper<T> queryWraper, String column, Object values) {
         if (needAddCondition(values)) {
         	Path<?> fieldPath = getPath(queryWraper.getRoot(), column);  //得到最终的路径
         	if(values.getClass().isArray()) {
         	    queryWraper.addPredicate(fieldPath.in((Object[])values));  //in :创建Predicate以测试表达式是否为参数列表的成员,返回Predicate 
             }else if(values instanceof Collection) {
                 queryWraper.addPredicate(fieldPath.in((Collection<?>)values));
             }
         }
     }
     
     /**
      * 添加between条件查询
      * @param queryWraper
      * @param experssion
      * @param minValue  范围下限
      * @param maxValue  范围上限
      */
     @SuppressWarnings({ "rawtypes", "unchecked" })
     protected void addBetweenConditionToColumn(QueryWraper<T> queryWraper, String column, Comparable minValue, Comparable maxValue) {
     	if (minValue != null || maxValue != null) {
     		Path<? extends Comparable> fieldPath = getPath(queryWraper.getRoot(), column);
     		if(minValue != null && maxValue != null){
     			queryWraper.addPredicate(queryWraper.getCb().between(fieldPath, minValue, processMaxValueOnDate(maxValue)));
     		}else if(minValue != null){
     			queryWraper.addPredicate(queryWraper.getCb().greaterThanOrEqualTo(fieldPath, minValue));
     		}else if(maxValue != null){
     			queryWraper.addPredicate(queryWraper.getCb().lessThanOrEqualTo(fieldPath, processMaxValueOnDate(maxValue)));
     		}
     	}
     }
    
     /**
      * 当范围查询的条件是小于,并且值的类型是Date时,将传入的Date值变为当天的夜里12点的值。
      * @param maxValue
      * @return
      * @author zhailiang
      * @since 2016年12月14日
      */
     @SuppressWarnings("rawtypes")
     private Comparable processMaxValueOnDate(Comparable maxValue) {
         if(maxValue instanceof Date) {
             maxValue = new DateTime(maxValue).withTimeAtStartOfDay().plusDays(1).plusSeconds(-1).toDate();
         }
         return maxValue;
     }
    
     /**
      * 添加大于条件查询
      * @param queryWraper
      * @param experssion
      * @param minValue
      */
     @SuppressWarnings({ "rawtypes", "unchecked" })
     protected void addGreaterThanConditionToColumn(QueryWraper<T> queryWraper, String column,  Comparable minValue) {
     	if (minValue != null) {
     		Path<? extends Comparable> fieldPath = getPath(queryWraper.getRoot(), column);
     		queryWraper.addPredicate(queryWraper.getCb().greaterThan(fieldPath, minValue));
     	}
     }
     
     /**
      * 添加大于等于条件查询
      * @param queryWraper
      * @param experssion
      * @param minValue
      */
     @SuppressWarnings({ "rawtypes", "unchecked" })
     protected void addGreaterThanOrEqualConditionToColumn(QueryWraper<T> queryWraper, String column,  Comparable minValue) {
     	if (minValue != null) {
     		Path<? extends Comparable> fieldPath = getPath(queryWraper.getRoot(), column);
     		queryWraper.addPredicate(queryWraper.getCb().greaterThanOrEqualTo(fieldPath, minValue));
     	}
     }
     
     /**
      * 添加小于条件查询
      * @param queryWraper
      * @param experssion
      * @param maxValue
      */
     @SuppressWarnings({ "unchecked", "rawtypes" })
     protected void addLessThanConditionToColumn(QueryWraper<T> queryWraper, String column,  Comparable maxValue) {
     	if (maxValue != null) {
     		Path<? extends Comparable> fieldPath = getPath(queryWraper.getRoot(), column);
     		queryWraper.addPredicate(queryWraper.getCb().lessThan(fieldPath, processMaxValueOnDate(maxValue)));
     	}
     }
    
     /**
      * 添加小于等于条件查询
      * @param queryWraper
      * @param experssion
      * @param maxValue
      */
     @SuppressWarnings({ "unchecked", "rawtypes" })
     protected void addLessThanOrEqualConditionToColumn(QueryWraper<T> queryWraper, String column,  Comparable maxValue) {
     	if (maxValue != null) {
     		Path<? extends Comparable> fieldPath = getPath(queryWraper.getRoot(), column);
     		queryWraper.addPredicate(queryWraper.getCb().lessThanOrEqualTo(fieldPath, processMaxValueOnDate(maxValue)));
     	}
     }
     
     /**
      * <pre>
      * 添加like条件
      * <pre>
      * @param queryWraper
      * @param column 指出要向哪个字段添加包含(like)条件
      * @param value  like什么
      * @author jojo 2014-8-12 下午3:13:44
      */
     protected void addLikeConditionToColumn(QueryWraper<T> queryWraper, String column, String value) {
     	if (StringUtils.isNotBlank(value)) {
     		queryWraper.addPredicate(createLikeCondition(queryWraper, column, value));
     	}
     }
     
     /**
      * @param queryWraper
      * @param column  查哪个字段
      * @param value  字段like什么
      * @return
      * @author zhailiang
      * @since 2016年12月13日
      */
     @SuppressWarnings("unchecked")
     protected Predicate createLikeCondition(QueryWraper<T> queryWraper, String column, String value) {
         Path<String> fieldPath = getPath(queryWraper.getRoot(), column);
         Predicate condition = queryWraper.getCb().like(fieldPath, "%" + value + "%");
         return condition;
     }
     
     /**
      * <pre>
      * 添加like条件
      * <pre>
      * @param queryWraper
      * @param column
      * @param value
      * @author jojo 2014-8-12 下午3:13:44
      */
     @SuppressWarnings("unchecked")
     protected void addStartsWidthConditionToColumn(QueryWraper<T> queryWraper, String column, String value) {
     	if (StringUtils.isNotBlank(value)) {
     		Path<String> fieldPath = getPath(queryWraper.getRoot(), column);
     		queryWraper.addPredicate(queryWraper.getCb().like(fieldPath,  value + "%"));
     	}
     }
    
    
     /**
      *  添加等于条件
      * @param queryWraper
      * @param column 指出要向哪个字段添加条件
      * @param value 指定字段的值
      */
     protected void addEqualsConditionToColumn(QueryWraper<T> queryWraper, String column, Object value) {
     	if(needAddCondition(value)) {
     		Path<?> fieldPath = getPath(queryWraper.getRoot(), column);
     		queryWraper.addPredicate(queryWraper.getCb().equal(fieldPath, value));
     	}
     }
     
     /**
      *  添加不等于条件
      * @param queryWraper
      * @param column 指出要向哪个字段添加条件
      * @param value 指定字段的值
      */
     protected void addNotEqualsConditionToColumn(QueryWraper<T> queryWraper, String column, Object value) {
     	if(needAddCondition(value)) {
     		Path<?> fieldPath = getPath(queryWraper.getRoot(), column);
     		queryWraper.addPredicate(queryWraper.getCb().notEqual(fieldPath, value));
     	}
     }
     
     /**
      * <pre>
      *
      * <pre>  得到属性的路径
      * @param root
      * @param property
      * @return
      * @author jojo 2014-8-12 下午3:06:58
      */
     @SuppressWarnings("rawtypes")
     protected Path getPath(Root root, String property){
     	//Path代表一个简单或者复杂的属性路径
     	String[] names = StringUtils.split(property, ".");  //比如路径是admin.role.resource,需要为resource创建path 
     	Path path = root.get(names[0]);
     	for (int i = 1; i < names.length; i++) {
     		path = path.get(names[i]);   //创建与引用属性相对应的路径
     	}
     	return path;
     }
    
     /**
      * <pre>
      * 判断是否需要添加where条件
      * <pre>
      * @param value
      * @return
      * @author jojo 2014-8-12 下午3:07:00
      */
     @SuppressWarnings("rawtypes")
     protected boolean needAddCondition(Object value) {
     	boolean addCondition = false;
     	if (value != null) {
     		if(value instanceof String) {
     			if(StringUtils.isNotBlank(value.toString())) {
     				addCondition = true;
     			}
     		}else if(value.getClass().isArray()) {
     			if(ArrayUtils.isNotEmpty((Object[]) value)) {
     				addCondition = true;
     			}
     		}else if(value instanceof Collection) {
     			if(CollectionUtils.isNotEmpty((Collection) value)) {
     				addCondition = true;
     			}
     		}else {
     			addCondition = true;
     		}
     	}
     	return addCondition;
     }
    
     }
    
  3. AbstractEventConditionBuilder抽象类,继承AbstractConditionBuilder类,根据传上来的条件对象,对AbstractConditionBuilder查询方法进行进一步封装。

     	public abstract class AbstractEventConditionBuilder<T, C> extends AbstractConditionBuilder<T> {
     
     	/**
     	 * 查询条件
     	 */
     	private C condition;
     	
     	/**
     	 * @param condition 查询条件
     	 */
     	public AbstractEventConditionBuilder(C condition){
     		this.condition = condition;
     	}
     
     	/**
     	 * 向查询中添加包含(like)条件
     	 * 
     	 * @param queryWraper
     	 * @param field 指出查询条件的值从condition对象的哪个字段里取,并且指出要向哪个字段添加包含(like)条件。(同一个字段名称)
     	 * @throws NoSuchMethodException 
     	 * @throws InvocationTargetException 
     	 * @throws IllegalAccessException 
     	 */
     	protected void addLikeCondition(QueryWraper<T> queryWraper, String field){
     		addLikeCondition(queryWraper, field, field);
     	}
     	
     	/**
     	 * 向查询中添加包含(like)条件
     	 * 
     	 * @param queryWraper
     	 * @param field 指出查询条件的值从condition对象的哪个字段里取
     	 * @param column 指出要向哪个字段添加包含(like)条件
     	 * @throws NoSuchMethodException 
     	 * @throws InvocationTargetException 
     	 * @throws IllegalAccessException 
     	 */
     	protected void addLikeCondition(QueryWraper<T> queryWraper, String field, String column){
     		addLikeConditionToColumn(queryWraper, column, (String) 
     				getValue(getCondition(), field));   //得到condition里面 field字段的值
     	}
     	
     	
     	/**
     	 * 向查询中添加包含(like)条件,%放在值后面
     	 * 
     	 * @param queryWraper
     	 * @param field 指出查询条件的值从condition对象的哪个字段里取,并且指出要向哪个字段添加包含(like)条件。(同一个字段名称)
     	 * @throws NoSuchMethodException 
     	 * @throws InvocationTargetException 
     	 * @throws IllegalAccessException 
     	 */
     	protected void addStartsWidthCondition(QueryWraper<T> queryWraper, String field){
     		addStartsWidthCondition(queryWraper, field, field);
     	}
     	
     	/**
     	 * 向查询中添加包含(like)条件,%放在值后面
     	 * 
     	 * @param queryWraper
     	 * @param field 指出查询条件的值从condition对象的哪个字段里取
     	 * @param column 指出要向哪个字段添加包含(like)条件
     	 * @throws NoSuchMethodException 
     	 * @throws InvocationTargetException 
     	 * @throws IllegalAccessException 
     	 */
     	protected void addStartsWidthCondition(QueryWraper<T> queryWraper, String field, String column){
     		addStartsWidthConditionToColumn(queryWraper, column, (String) 
     				getValue(getCondition(), field));
     	}
     		
     	/**
     	 * 向查询中添加等于(=)条件
     	 * 
     	 * @param queryWraper
     	 * @param field 指出查询条件的值从condition对象的哪个字段里取,并且指出要向哪个字段添加条件。(同一个字段名称)
     	 * @throws NoSuchMethodException 
     	 * @throws InvocationTargetException 
     	 * @throws IllegalAccessException 
     	 */
     	protected void addEqualsCondition(QueryWraper<T> queryWraper, String field){
     		addEqualsCondition(queryWraper, field, field);
     	}
     	
     	/**
     	 * 向查询中添加等于(=)条件
     	 * 
     	 * @param queryWraper
     	 * @param field 指出查询条件的值从condition对象的哪个字段里取
     	 * @param column 指出要向哪个字段添加条件
     	 * @throws NoSuchMethodException 
     	 * @throws InvocationTargetException 
     	 * @throws IllegalAccessException 
     	 */
     	protected void addEqualsCondition(QueryWraper<T> queryWraper, String field, String column){
     		addEqualsConditionToColumn(queryWraper, column, 
     				getValue(getCondition(), field));
     	}
     	
     	/**
     	 * 向查询中添加不等于(!=)条件
     	 * 
     	 * @param queryWraper
     	 * @param field 指出查询条件的值从condition对象的哪个字段里取,并且指出要向哪个字段添加条件。(同一个字段名称)
     	 * @throws NoSuchMethodException 
     	 * @throws InvocationTargetException 
     	 * @throws IllegalAccessException 
     	 */
     	protected void addNotEqualsCondition(QueryWraper<T> queryWraper, String field){
     		addNotEqualsCondition(queryWraper, field, field);
     	}
     	
     	/**
     	 * 向查询中添加等于(=)条件
     	 * 
     	 * @param queryWraper
     	 * @param field 指出查询条件的值从condition对象的哪个字段里取
     	 * @param column 指出要向哪个字段添加条件
     	 * @throws NoSuchMethodException 
     	 * @throws InvocationTargetException 
     	 * @throws IllegalAccessException 
     	 */
     	protected void addNotEqualsCondition(QueryWraper<T> queryWraper, String field, String column){
     		addNotEqualsConditionToColumn(queryWraper, column, getValue(getCondition(), field));
     	}
     	
     	/**
     	 * <pre>
     	 * 向查询中添加in条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @author jojo 2014-8-12 下午3:26:50
     	 */
     	protected void addInCondition(QueryWraper<T> queryWraper, String field) {
     		addInCondition(queryWraper, field, field);
     	}
     	/**
     	 * <pre>
     	 * 向查询中添加in条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @param column
     	 * @author jojo 2014-8-12 下午3:27:46
     	 */
     	protected void addInCondition(QueryWraper<T> queryWraper, String field, String column) {
     		addInConditionToColumn(queryWraper, column, 
     				getValue(getCondition(), field));
     	}
     	
     	/**
     	 * <pre>
     	 * 向查询中添加between条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @author jojo 2014-8-12 下午3:26:50
     	 */
     	protected void addBetweenCondition(QueryWraper<T> queryWraper, String field) {
     		addBetweenCondition(queryWraper, field, field+"To", field);
     	}
     	/**
     	 * <pre>
     	 * 向查询中添加between条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @param column
     	 * @author jojo 2014-8-12 下午3:27:46
     	 */
     	@SuppressWarnings("rawtypes")
     	protected void addBetweenCondition(QueryWraper<T> queryWraper, String startField, String endField, String column) {
     		addBetweenConditionToColumn(queryWraper, column, 
     				(Comparable)getValue(getCondition(), startField), 
     				(Comparable)getValue(getCondition(), endField));
     	}
     	
     	/**
     	 * <pre>
     	 * 向查询中添加大于条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @author jojo 2014-8-12 下午3:26:50
     	 */
     	protected void addGreaterThanCondition(QueryWraper<T> queryWraper, String field) {
     		addGreaterThanCondition(queryWraper, field, field);
     	}
     	/**
     	 * <pre>
     	 * 向查询中添加大于条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @param column
     	 * @author jojo 2014-8-12 下午3:27:46
     	 */
     	@SuppressWarnings("rawtypes")
     	protected void addGreaterThanCondition(QueryWraper<T> queryWraper, String field, String column) {
     		addGreaterThanConditionToColumn(queryWraper, column, 
     				(Comparable)getValue(getCondition(), field));
     	}
     	
     	/**
     	 * <pre>
     	 * 向查询中添加大于等于条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @author jojo 2014-8-12 下午3:26:50
     	 */
     	protected void addGreaterThanOrEqualCondition(QueryWraper<T> queryWraper, String field) {
     		addGreaterThanOrEqualCondition(queryWraper, field, field);
     	}
     	
     	/**
     	 * <pre>
     	 * 向查询中添加大于等于条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @param column
     	 * @author jojo 2014-8-12 下午3:27:46
     	 */
     	@SuppressWarnings("rawtypes")
     	protected void addGreaterThanOrEqualCondition(QueryWraper<T> queryWraper, String field, String column) {
     		addGreaterThanOrEqualConditionToColumn(queryWraper, column, 
     				(Comparable)getValue(getCondition(), field));
     	}
     	
     	/**
     	 * <pre>
     	 * 向查询中添加小于条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @author jojo 2014-8-12 下午3:26:50
     	 */
     	protected void addLessThanCondition(QueryWraper<T> queryWraper, String field) {
     		addLessThanCondition(queryWraper, field, field);
     	}
     	/**
     	 * <pre>
     	 * 向查询中添加小于条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @param column
     	 * @author jojo 2014-8-12 下午3:27:46
     	 */
     	@SuppressWarnings("rawtypes")
     	protected void addLessThanCondition(QueryWraper<T> queryWraper, String field, String column) {
     		addLessThanConditionToColumn(queryWraper, column, 
     				(Comparable)getValue(getCondition(), field));
     	}
     
     	/**
     	 * <pre>
     	 * 向查询中添加小于等于条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @author jojo 2014-8-12 下午3:26:50
     	 */
     	protected void addLessThanOrEqualCondition(QueryWraper<T> queryWraper, String field) {
     		addLessThanOrEqualCondition(queryWraper, field, field);
     	}
     	
     	/**
     	 * <pre>
     	 * 向查询中添加小于等于条件
     	 * <pre>
     	 * @param queryWraper
     	 * @param field
     	 * @param column
     	 * @author jojo 2014-8-12 下午3:27:46
     	 */
     	@SuppressWarnings("rawtypes")
     	protected void addLessThanOrEqualCondition(QueryWraper<T> queryWraper, String field, String column) {
     		addLessThanOrEqualConditionToColumn(queryWraper, column, 
     				(Comparable)getValue(getCondition(), field));
     	}
     
     	/**
     	 * 
     	 * @param condition 从这个对象里面查
     	 * @param field  要查询的属性
     	 * @return
     	 */
     	private Object getValue(C condition, String field) {
     		try {
     			//得到condition对象中field属性的值
     			//使用示例:getProperty(book,"authors[0].favorites(food)")
     			return PropertyUtils.getProperty(condition, field);
     		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
     			e.printStackTrace();
     		}
     		return null;
     	}
     
     	/**
     	 * @return the condition
     	 */
     	public C getCondition() {
     		return condition;
     	}
     
     	/**
     	 * @param condition the condition to set
     	 */
     	public void setCondition(C condition) {
     		this.condition = condition;
     	}
     	
     	}
    
  4. MyImoocSpecification类,继承AbstractEventConditionBuilder类,并实现Specification接口,重写toPredicate()方法,使用时继承该类即可

     	public abstract class MySpecification<T, C> extends AbstractEventConditionBuilder<T, C> implements Specification<T> {
     		//AbstractEventConditionBuilder里面封装了添加各种查询条件的方法
     	/**
     	 * @param condition
     	 */
     	public MySpecification(C condition) {
     		super(condition);
     	}
     
     	/**
     	 * 
     	 * 构建查询条件,子类必须实现addCondition方法来编写查询的逻辑。
     	 * 
     	 * 子类可以通过addFetch方法控制查询的关联和抓取行为。
     	 * 
     	 */
     	@Override
     	public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
     
     		if (Long.class != query.getResultType()) {
     			addFetch(root);
     		}
     
     		List<Predicate> predicates = new ArrayList<Predicate>();
     
     		QueryWraper<T> queryWraper = new QueryWraper<T>(root, query, cb, predicates);
     
     		addCondition(queryWraper);
     
     		Predicate permissionCondition = getPermissionCondition(queryWraper);
     		if (permissionCondition != null) {
     			queryWraper.addPredicate(permissionCondition);
     		}
     
     		return cb.and(predicates.toArray(new Predicate[predicates.size()]));
     	}
     
     	/**
     	 * 添加权限条件,如果要查询的domain实现了{@link ManagedByOrgan}接口,那么传入的Condition对象也应该实现
     	 * {@link ManagedByOrgan}接口,
     	 * 程序会尝试从Condition对象获取organFullId,然后作为like查询条件添加到查询中。
     	 * 查出所有以传入的organFullId开头的domain.
     	 * 
     	 * @param queryWraper
     	 * @return
     	 */
     	protected Predicate getPermissionCondition(QueryWraper<T> queryWraper) {
     		return null;
     	}
     
     	/**
     	 * <pre>
     	 * 子类可以通过覆盖此方法实现关联抓取,避免n+1查询
     	 * 
     	 * <pre>
     	 * 
     	 * @param root
     	 * @author jojo 2014-7-22 上午9:49:26
     	 */
     	protected void addFetch(Root<T> root) {
     		
     	}
     
     	protected abstract void addCondition(QueryWraper<T> queryWraper);  //钩子方法,子类实现 自动调用
     
     }
    

三、使用示例

3.1 创建条件封装对象

public class AdminCondition {

	private String username;

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}
}

3.2 继承MySpecification类

传入条件封装对象,以及结果实体类型
public class AdminSpec extends ImoocSpecification<Admin, AdminCondition> {

	public AdminSpec(AdminCondition condition) {
		super(condition);
	}

	@Override
	protected void addCondition(QueryWraper<Admin> queryWraper) {
		addLikeCondition(queryWraper, "username");
	}

}

3.3 调用

public class AdminServiceImpl implements AdminService {

@Autowired
private AdminRepository adminRepository;

	public Page<AdminInfo> query(AdminCondition condition, Pageable pageable) {
	Page<Admin> admins = adminRepository.findAll(new AdminSpec(condition), pageable);
	return QueryResultConverter.convert(admins, AdminInfo.class, pageable);
	}
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值