1、定义条件容器
package cn.aid.common.utils.jpa.condition; import org.springframework.data.jpa.domain.Specification; import javax.persistence.criteria.*; import java.util.ArrayList; import java.util.List; /** * 定义一个查询条件容器 * Created by gzs */ public class Criteriaimplements Specification { private List criterions = new ArrayList<>(); private List orders = new ArrayList<>(); @Override public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder builder) { if (!criterions.isEmpty()) { List predicates = new ArrayList<>(); for (Criterion c : criterions) { predicates.add(c.toPredicate(root, query, builder)); } for (Criterion c : orders) { Order order = c.toOrder(root, query, builder); query.orderBy(order); } // 将所有条件用 and 联合起来 if (predicates.size() > 0) { return builder.and(predicates.toArray(new Predicate[predicates.size()])); } } return builder.conjunction(); } /** * 增加简单条件表达式 * * @Methods Name add * @Create In 2018-10-15 By gzs */ public void add(Criterion criterion) { if (criterion != null) { criterions.add(criterion); } } /** * 增加排序表达式 * * @Methods Name add * @Create In 2018-11-15 By gzs */ public void addOrder(Criterion order) { if (order != null) { orders.add(order); } } }
2、条件表达式
package cn.aid.common.utils.jpa.condition; import javax.persistence.criteria.*; /** * 创建条件表达式接口,模拟系统的条件查询 * Created by gzs */ public interface Criterion { enum Operator { EQ, NE, LIKE, GT, LT, GTE, LTE, AND, OR, IS_MEMBER, IS_NOT_MEMBER, DESC, ASC } Predicate toPredicate(Root> root, CriteriaQuery> query, CriteriaBuilder builder); Order toOrder(Root> root, CriteriaQuery> query, CriteriaBuilder builder); }
3、实现逻辑条件表达式
package cn.aid.common.utils.jpa.condition; import javax.persistence.criteria.*; import java.util.ArrayList; import java.util.List; /** * 逻辑条件表达式 用于复杂条件时使用,如单属性多对应值的OR查询等 * * Created by gzs */ public class LogicalExpression implements Criterion { /** * 逻辑表达式中包含的表达式 */ private Criterion[] criterion; /** * 计算符 */ private Operator operator; public LogicalExpression(Criterion[] criterions, Operator operator) { this.criterion = criterions; this.operator = operator; } @Override public Predicate toPredicate(Root> root, CriteriaQuery> query, CriteriaBuilder builder) { Listpredicates = new ArrayList<>(); for (int i = 0; i < this.criterion.length; i++) { predicates.add(this.criterion[i].toPredicate(root, query, builder)); } switch (operator) { case OR: return builder.or(predicates.toArray(new Predicate[predicates.size()])); default: return null; } } @Override public Order toOrder(Root> root, CriteriaQuery> query, CriteriaBuilder builder) { return null; } }
4、实现简单条件表达式
package cn.aid.common.utils.jpa.condition; import org.springframework.util.StringUtils; import javax.persistence.criteria.*; import java.util.List; import java.util.Map; import java.util.Set; /** * 简单条件表达式 * * Created by gzs */ public class SimpleExpression implements Criterion { /** * 属性名 */ private String fieldName; /** * 对应值 */ private Object value; /** * 计算符 */ private Operator operator; protected SimpleExpression(String fieldName, Object value, Operator operator) { this.fieldName = fieldName; this.value = value; this.operator = operator; } @Override @SuppressWarnings({"rawtypes", "unchecked"}) public Predicate toPredicate(Root> root, CriteriaQuery> query, CriteriaBuilder builder) { Path expression; //此处是表关联数据,注意仅限一层关联,如user.address, //查询user的address集合中,address的name为某个值 if (fieldName.contains(".")) { String[] names = StringUtils.split(fieldName, "."); //获取该属性的类型,Set?List?Map? expression = root.get(names[0]); Class clazz = expression.getJavaType(); if (clazz.equals(Set.class)) { SetJoin setJoin = root.joinSet(names[0]); expression = setJoin.get(names[1]); } else if (clazz.equals(List.class)) { ListJoin listJoin = root.joinList(names[0]); expression = listJoin.get(names[1]); } else if (clazz.equals(Map.class)) { MapJoin mapJoin = root.joinMap(names[0]); expression = mapJoin.get(names[1]); } else { //是many to one时 expression = expression.get(names[1]); } } else { //单表查询 expression = root.get(fieldName); } switch (operator) { case EQ: return builder.equal(expression, value); case NE: return builder.notEqual(expression, value); case LIKE: return builder.like((Expression) expression, "%" + value + "%"); case LT: return builder.lessThan(expression, (Comparable) value); case GT: return builder.greaterThan(expression, (Comparable) value); case LTE: return builder.lessThanOrEqualTo(expression, (Comparable) value); case GTE: return builder.greaterThanOrEqualTo(expression, (Comparable) value); case IS_MEMBER: return builder.isMember(value, expression); case IS_NOT_MEMBER: return builder.isNotMember(value, expression); default: return null; } } @Override public Order toOrder(Root> root, CriteriaQuery> query, CriteriaBuilder builder) { return null; } }
5、实现排序表达式
package cn.aid.common.utils.jpa.condition; import org.springframework.util.StringUtils; import javax.persistence.criteria.*; import java.util.List; import java.util.Map; import java.util.Set; /** * 逻辑条件表达式 用于复杂条件时使用,如单属性多对应值的OR查询等 * * Created by gzs */ public class OrderExpression implements Criterion { /** * 计算符 */ private Operator operator; /** * 属性名 */ private String fieldName; public OrderExpression(String fieldName, Operator operator) { this.fieldName = fieldName; this.operator = operator; } @Override public Predicate toPredicate(Root> root, CriteriaQuery> query, CriteriaBuilder builder) { return null; } @Override public Order toOrder(Root> root, CriteriaQuery> query, CriteriaBuilder builder) { Path expression; //此处是表关联数据,注意仅限一层关联,如user.address, //查询user的address集合中,address的name为某个值 if (fieldName.contains(".")) { String[] names = StringUtils.split(fieldName, "."); //获取该属性的类型,Set?List?Map? expression = root.get(names[0]); Class clazz = expression.getJavaType(); if (clazz.equals(Set.class)) { SetJoin setJoin = root.joinSet(names[0]); expression = setJoin.get(names[1]); } else if (clazz.equals(List.class)) { ListJoin listJoin = root.joinList(names[0]); expression = listJoin.get(names[1]); } else if (clazz.equals(Map.class)) { MapJoin mapJoin = root.joinMap(names[0]); expression = mapJoin.get(names[1]); } else { //是many to one时 expression = expression.get(names[1]); } } else { //单表查询 expression = root.get(fieldName); } switch (operator) { case DESC: return builder.desc(expression); default: return builder.asc(expression); } } } 7、条件构造器
package cn.aid.common.utils.jpa.condition; import org.springframework.util.StringUtils; import java.util.Collection; /** * 条件构造器 * 用于创建条件表达式 * * Created by gzs */ public class Restrictions { /** * 等于 */ public static SimpleExpression eq(String fieldName, Object value, boolean ignoreNull) { if (ignoreNull && StringUtils.isEmpty(value)) { return null; } return new SimpleExpression(fieldName, value, Criterion.Operator.EQ); } /** * 集合包含某个元素 */ public static SimpleExpression hasMember(String fieldName, Object value, boolean ignoreNull) { if (ignoreNull && StringUtils.isEmpty(value)) { return null; } return new SimpleExpression(fieldName, value, Criterion.Operator.IS_MEMBER); } /** * 不等于 */ public static SimpleExpression ne(String fieldName, Object value, boolean ignoreNull) { if (ignoreNull && StringUtils.isEmpty(value)) { return null; } return new SimpleExpression(fieldName, value, Criterion.Operator.NE); } /** * 模糊匹配 */ public static SimpleExpression like(String fieldName, String value, boolean ignoreNull) { if (ignoreNull && StringUtils.isEmpty(value)) { return null; } return new SimpleExpression(fieldName, value, Criterion.Operator.LIKE); } /** */ // public static SimpleExpression like(String fieldName, String value, // MatchMode matchMode, boolean ignoreNull) { // if (StringUtils.isEmpty(value)) return null; // return null; // } /** * 大于 */ public static SimpleExpression gt(String fieldName, Object value, boolean ignoreNull) { if (ignoreNull && StringUtils.isEmpty(value)) { return null; } return new SimpleExpression(fieldName, value, Criterion.Operator.GT); } /** * 小于 */ public static SimpleExpression lt(String fieldName, Object value, boolean ignoreNull) { if (ignoreNull && StringUtils.isEmpty(value)) { return null; } return new SimpleExpression(fieldName, value, Criterion.Operator.LT); } /** * 小于等于 */ public static SimpleExpression lte(String fieldName, Object value, boolean ignoreNull) { if (ignoreNull && StringUtils.isEmpty(value)) { return null; } return new SimpleExpression(fieldName, value, Criterion.Operator.GTE); } /** * 大于等于 */ public static SimpleExpression gte(String fieldName, Object value, boolean ignoreNull) { if (ignoreNull && StringUtils.isEmpty(value)) { return null; } return new SimpleExpression(fieldName, value, Criterion.Operator.LTE); } /** * 降序 */ public static OrderExpression desc(String fieldName) { /*if (StringUtils.isEmpty(fieldName)) { return null; }*/ return new OrderExpression(fieldName, Criterion.Operator.DESC); } /** * 升序 */ public static OrderExpression asc(String fieldName) { /*if (StringUtils.isEmpty(fieldName)) { return null; }*/ return new OrderExpression(fieldName, Criterion.Operator.ASC); } /** * 并且 */ public static LogicalExpression and(Criterion... criterions) { return new LogicalExpression(criterions, Criterion.Operator.AND); } /** * 或者 */ public static LogicalExpression or(Criterion... criterions) { return new LogicalExpression(criterions, Criterion.Operator.OR); } /** * 包含于 */ @SuppressWarnings("rawtypes") public static LogicalExpression in(String fieldName, Collection value, boolean ignoreNull) { if (ignoreNull && (value == null || value.isEmpty())) { return null; } SimpleExpression[] ses = new SimpleExpression[value.size()]; int i = 0; for (Object obj : value) { ses[i] = new SimpleExpression(fieldName, obj, Criterion.Operator.EQ); i++; } return new LogicalExpression(ses, Criterion.Operator.OR); } /** * 集合包含某几个元素,譬如可以查询User类中Setset包含"ABC","bcd"的User集合, * 或者查询User中Set的Address的name为"北京"的所有User集合 * 集合可以为基本类型或者JavaBean,可以是one to many或者是@ElementCollection * @param fieldName * 列名 * @param value * 集合 * @return * expresssion */ public static LogicalExpression hasMembers(String fieldName, Object... value) { SimpleExpression[] ses = new SimpleExpression[value.length]; int i = 0; //集合中对象是基本类型,如Set ,List Criterion.Operator operator = Criterion.Operator.IS_MEMBER; //集合中对象是JavaBean if (fieldName.contains(".")) { operator = Criterion.Operator.EQ; } for (Object obj : value) { ses[i] = new SimpleExpression(fieldName, obj, operator); i++; } return new LogicalExpression(ses, Criterion.Operator.OR); } }
8、见证奇迹的时刻来了demo
if (StringUtils.isNotBlank(teacher.getContactName())) { //动态查询 Criteriacriteria = new Criteria<>(); final LogicalExpression or = Restrictions.or( Restrictions.like("code", teacher.getContactName(), true), Restrictions.like("contactName", teacher.getContactName(), true), Restrictions.like("mobile", teacher.getContactName(), true)); criteria.add(or); criteria.add(Restrictions.eq("groupMerchantId", teacher.getGroupMerchantId(), true)); criteria.add(Restrictions.eq("merchantId", teacher.getMerchantId(), true)); criteria.add(Restrictions.eq("campusId", teacher.getCampusId(), true)); criteria.addOrder(Restrictions.desc("gmtModified")); Pageable pageable = new PageRequest(pageNo - 1, pageSize); //页码:前端从1开始,jpa从0开始,做个转换 org.springframework.data.domain.Page cmsUsers = teacherRepository.findAll(criteria, pageable);