springdata中Specification查询封装
2017-05-31 00:00
507 查看
1、定义操作符类:
package net.sppan.base.service.specification; /** * 操作符类,这个类中存储了键值对和操作符号,另外存储了连接下一个条件的类型是and还是or * <br> * 创建时通过 id>=7,其中id就是key,>=就是oper操作符,7就是value * <br> * 特殊的自定义几个操作符(:表示like %v%,b:表示v%,:b表示%v) */ public class SpecificationOperator { /** * 操作符的key,如查询时的name,id之类 */ private String key; /** * 操作符的value,具体要查询的值 */ private Object value; /** * 操作符,自己定义的一组操作符,用来方便查询 */ private String oper; /** * 连接的方式:and或者or */ private String join; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } public String getOper() { return oper; } public void setOper(String oper) { this.oper = oper; } public String getJoin() { return join; } public void setJoin(String join) { this.join = join; } public static enum Operator { eq, ge, le, gt, lt, likeL, likeR, likeAll, isNull, isNotNull, notEqual; @Override public String toString() { return name(); } } public static enum Join { and, or; @Override public String toString() { return name(); } } }
2、Specification实现类:
package net.sppan.base.service.specification; import net.sppan.base.service.specification.SpecificationOperator.Join; import org.springframework.data.jpa.domain.Specification; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import java.util.List; public class SimpleSpecification<T> implements Specification<T> { /** * 查询的条件列表,是一组列表 * */ private List<SpecificationOperator> opers; public SimpleSpecification(List<SpecificationOperator> opers) { this.opers = opers; } @Override public Predicate toPredicate(Root<T> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { int index = 0; //通过resultPre来组合多个条件 Predicate resultPre = null; for(SpecificationOperator op:opers) { if(index++==0) { resultPre = generatePredicate(root,criteriaBuilder,op); continue; } Predicate pre = generatePredicate(root,criteriaBuilder,op); if(pre==null) continue; if(Join.and.name().equalsIgnoreCase(op.getJoin())) { resultPre = criteriaBuilder.and(resultPre,pre); } else if(Join.or.name().equalsIgnoreCase(op.getJoin())) { resultPre = criteriaBuilder.or(resultPre,pre); } } return resultPre; } private Predicate generatePredicate(Root<T> root,CriteriaBuilder criteriaBuilder, SpecificationOperator op) { /* * 根据不同的操作符返回特定的查询*/ if(SpecificationOperator.Operator.eq.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.equal(root.get(op.getKey()),op.getValue()); } else if(SpecificationOperator.Operator.ge.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.ge(root.get(op.getKey()).as(Number.class), (Number)op.getValue()); } else if(SpecificationOperator.Operator.le.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.le(root.get(op.getKey()).as(Number.class),(Number)op.getValue()); } else if(SpecificationOperator.Operator.gt.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.gt(root.get(op.getKey()).as(Number.class),(Number)op.getValue()); } else if(SpecificationOperator.Operator.lt.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.lt(root.get(op.getKey()).as(Number.class),(Number)op.getValue()); } else if(SpecificationOperator.Operator.likeAll.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.like(root.get(op.getKey()).as(String.class),"%"+op.getValue()+"%"); } else if(SpecificationOperator.Operator.likeL.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.like(root.get(op.getKey()).as(String.class),op.getValue()+"%"); } else if(SpecificationOperator.Operator.likeR.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.like(root.get(op.getKey()).as(String.class),"%"+op.getValue()); } else if(SpecificationOperator.Operator.isNull.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.isNull(root.get(op.getKey())); } else if(SpecificationOperator.Operator.isNotNull.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.isNotNull(root.get(op.getKey())); } else if(SpecificationOperator.Operator.notEqual.name().equalsIgnoreCase(op.getOper())) { return criteriaBuilder.notEqual(root.get(op.getKey()),op.getValue()); } return null; } }
3、查询条件构造类:
package net.sppan.base.service.specification; import java.util.ArrayList; import java.util.List; import net.sppan.base.service.specification.SpecificationOperator.Join; import org.springframework.data.jpa.domain.Specification; public class SimpleSpecificationBuilder<T> { /** * 条件列表 */ private List<SpecificationOperator> opers; /** * 构造函数,初始化的条件是and */ public SimpleSpecificationBuilder(String key,String oper,Object value) { SpecificationOperator so = new SpecificationOperator(); so.setJoin(Join.and.name()); so.setKey(key); so.setOper(oper); so.setValue(value); opers = new ArrayList<SpecificationOperator>(); opers.add(so); } public SimpleSpecificationBuilder() { opers = new ArrayList<SpecificationOperator>(); } /** * 完成条件的添加 * @return */ public SimpleSpecificationBuilder<T> add(String key,String oper,Object value,String join) { SpecificationOperator so = new SpecificationOperator(); so.setKey(key); so.setValue(value); so.setOper(oper); so.setJoin(join); opers.add(so); return this; } /** * 添加or条件的重载 * @return this,方便后续的链式调用 */ public SimpleSpecificationBuilder<T> addOr(String key,String oper,Object value) { return this.add(key,oper,value,Join.or.name()); } /** * 添加and的条件 * @return */ public SimpleSpecificationBuilder<T> add(String key,String oper,Object value) { return this.add(key,oper,value,Join.and.name()); } public Specification<T> generateSpecification() { Specification<T> specification = new SimpleSpecification<T>(opers); return specification; } }
4、使用示例
SimpleSpecificationBuilder<Resource> builder = new SimpleSpecificationBuilder<Resource>();//Resource 持久层实体 builder.add("name", Operator.likeAll.name(), "keyword"); Specification specification = builder.generateSpecification()
相关文章推荐
- SpringDataJpa的Specification查询
- SpringDataJpa的Specification查询
- spring data jpa 动态查询(工具类封装)
- SpringDataJPA 查询封装
- SpringDataJPA学习记录(三)--复杂查询的封装
- spring-data-elasticsearch + java 查询方法的封装
- SpringDataJpa的Specification查询
- SpringDataJpa的Specification查询
- spring data jpa的动态查询封装(转)
- Spring data JPA使用Specification实现动态查询例子
- spring-data-jpa Specification 拼接复杂查询
- SpringDataJPA学习记录(三)--复杂查询的封装
- Spring data jpa 实现简单动态查询的通用Specification方法
- Spring Data JpaSpecificationExecutor 做复杂查询
- Spring Data JPA可以通过Specification进行动态查询
- Spring data jpa Specification查询关于日期的范围搜索
- SpringDataJpa的Specification查询
- SpringDataJpa的Specification查询
- spring data jpa specification的封装
- SpringDataJPA学习记录(三)--复杂查询的封装