package mybatisex.core.mapper; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.ibatis.ognl.OgnlRuntime; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.ObjectUtils; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils; /** * @Description 拼接查询条件工具类 */ public class QueryWrapperUtil { /** * 得到父类的对象 * * @param 查询的泛型 * @param clazz * @return */ public static List reflectForField(Class clazz) { Class tmpClazz = clazz; List fieldList = new ArrayList<>(); while (tmpClazz != null) { // 处理去掉静态属性 for (Field f : tmpClazz.getDeclaredFields()) { if (!Modifier.isStatic(f.getModifiers())) { fieldList.add(f); } } tmpClazz = tmpClazz.getSuperclass(); } return fieldList; } /** * 拼接查询条件 * * @param obj 数据实体 * @return void 返回参数说明 * @exception/throws */ public static QueryWrapper convertQuery(Object obj, QueryMap... map) { QueryMap param = new QueryMap(); if (ArrayUtils.isNotEmpty(map)) { param = map[0]; } QueryWrapper queryWrapper = new QueryWrapper<>(); Class clazz = obj.getClass(); try { // TODO 这里应该通过共有方法来进行反射 for (Field field : reflectForField(clazz)) { // 抑制Java对修饰符的检查 // field.setAccessible(true); // 获取属性值 // Object fieldValue = field.get(obj); // String fieldValue = getFieldValue(obj ,field.getName()).toString(); TableField tableField = AnnotationUtils.getAnnotation(field, TableField.class); // 字段没有TableField这个注解和有这个主机上false的 // 这里有可能没有注解,是使用了骆驼ming'm if (tableField != null && !tableField.exist()) { continue; } // String methodName = "set" + filedName.substring(0, 1).toUpperCase() + // filedName.substring(1); // 获取属性名 String name = field.getName(); // 声明属性描述对象 // PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, clazz); // Method method = clazz.getDeclaredMethod(propertyName); // 获取getter方法 // Method method = propertyDescriptor.getReadMethod(); // String getMethod = getMethod(name); Method method = getMethod(clazz, name); if (method == null) { continue; } Object fieldValue = method.invoke(obj); String fieldName; if (tableField == null) { fieldName = StringUtils.camelToUnderline(name); } else { fieldName = tableField.value(); } // 默认是相等 QueryWapper queryWapperAnnotation = AnnotationUtils.getAnnotation(field, QueryWapper.class); if (ObjectUtils.isEmpty(queryWapperAnnotation)) { queryWrapper.eq(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); } else { // 获取枚举 QueryKeyword[] queryWapperEnums = queryWapperAnnotation.value(); for (QueryKeyword queryWapperEnum : queryWapperEnums) { // 拼接查询条件 switch (queryWapperEnum) { case NE: queryWrapper.ne(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; // 这里需要,修改为集合 case IN: if (fieldValue != null) if (fieldValue.toString().contains(",")) { List result = Arrays.asList(fieldValue.toString().split(",")); queryWrapper.in(!ObjectUtils.isEmpty(fieldValue), fieldName, result); } else { queryWrapper.in(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); } break; case GT: queryWrapper.gt(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; case EQ: queryWrapper.eq(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; case GE: queryWrapper.ge(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; case LT: queryWrapper.lt(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; case LE: queryWrapper.le(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; case LIKE: queryWrapper.like(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; case NOT_LIKE: queryWrapper.notLike(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; case LIKE_LEFT: queryWrapper.likeLeft(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; case LIKE_RIGHT: queryWrapper.likeRight(!ObjectUtils.isEmpty(fieldValue), fieldName, fieldValue); break; case DESC: queryWrapper.orderByDesc(fieldName); break; case AND: // 通过attribute指定多个字段做AND连接(格式:{"field1", "field2"}) String[] andFields = queryWapperAnnotation.attribute(); if (ArrayUtils.isNotEmpty(andFields)) { for (String andField : andFields) { Method andMethod = getMethod(clazz, andField); if (andMethod == null) { continue; } Object andValue = andMethod.invoke(obj); if (!ObjectUtils.isEmpty(andValue)) { String dbAndField = getDbFieldName(clazz, andField); queryWrapper.eq(true, dbAndField, andValue); } } } break; case BETWEEN: // attribute指定开始/结束字段(格式:{"startField", "endField"}) String[] betweenFields = queryWapperAnnotation.attribute(); if (betweenFields.length == 2) { Method startMethod = getMethod(clazz, betweenFields[0]); Object startVal = startMethod != null ? startMethod.invoke(obj) : null; Method endMethod = getMethod(clazz, betweenFields[1]); Object endVal = endMethod != null ? endMethod.invoke(obj) : null; boolean betweenCondition = !ObjectUtils.isEmpty(startVal) && !ObjectUtils.isEmpty(endVal); queryWrapper.between(betweenCondition, fieldName, startVal, endVal); } break; case EXISTS: // attribute[0]传入EXISTS子查询SQL String[] existsSql = queryWapperAnnotation.attribute(); if (ArrayUtils.isNotEmpty(existsSql) && !StringUtils.isBlank(existsSql[0])) { queryWrapper.exists(existsSql[0]); } break; case GROUP_BY: // attribute指定分组字段(格式:{"field1", "field2"}) String[] groupFields = queryWapperAnnotation.attribute(); if (ArrayUtils.isNotEmpty(groupFields)) { for (String groupField : groupFields) { if (StringUtils.isBlank(groupField)) { continue; } String dbGroupField = getDbFieldName(clazz, groupField); queryWrapper.groupBy(dbGroupField); } } break; case HAVING: // attribute[0]直接写having条件SQL String[] havingConditions = queryWapperAnnotation.attribute(); if (ArrayUtils.isNotEmpty(havingConditions) && !StringUtils.isBlank(havingConditions[0])) { queryWrapper.having(havingConditions[0]); } break; case IS_NOT_NULL: queryWrapper.isNotNull(fieldName); break; case IS_NULL: queryWrapper.isNull(fieldName); break; case NOT: // attribute[0]指定要取反的字段 String[] notFields = queryWapperAnnotation.attribute(); if (ArrayUtils.isNotEmpty(notFields)) { String notField = notFields[0]; Method notMethod = getMethod(clazz, notField); if (notMethod != null) { Object notValue = notMethod.invoke(obj); if (!ObjectUtils.isEmpty(notValue)) { String dbNotField = getDbFieldName(clazz, notField); queryWrapper.not(true, i -> i.eq(dbNotField, notValue)); } } } break; case NOT_BETWEEN: String[] notBetweenFields = queryWapperAnnotation.attribute(); if (notBetweenFields.length == 2) { Method notStartMethod = getMethod(clazz, notBetweenFields[0]); Object notStartVal = notStartMethod != null ? notStartMethod.invoke(obj) : null; Method notEndMethod = getMethod(clazz, notBetweenFields[1]); Object notEndVal = notEndMethod != null ? notEndMethod.invoke(obj) : null; boolean notBetweenCondition = !ObjectUtils.isEmpty(notStartVal) && !ObjectUtils.isEmpty(notEndVal); queryWrapper.notBetween(notBetweenCondition, fieldName, notStartVal, notEndVal); } break; case NOT_EXISTS: String[] notExistsSql = queryWapperAnnotation.attribute(); if (ArrayUtils.isNotEmpty(notExistsSql) && !StringUtils.isBlank(notExistsSql[0])) { queryWrapper.notExists(notExistsSql[0]); } break; case NOT_IN: if (fieldValue != null && fieldValue.toString().contains(",")) { List notInList = Arrays.asList(fieldValue.toString().split(",")); if (!ObjectUtils.isEmpty(notInList)) { queryWrapper.notIn(true, fieldName, notInList); } } break; case OR: queryWrapper.or(); break; case ORDER_BY: // 支持多字段排序(格式:{"field1,asc", "field2,desc"}) String[] orderRules = queryWapperAnnotation.attribute(); if (ArrayUtils.isNotEmpty(orderRules)) { for (String rule : orderRules) { if (StringUtils.isBlank(rule)) { continue; } String[] parts = rule.split(",", 2); String orderField = parts[0].trim(); if (StringUtils.isBlank(orderField)) { continue; } String direction = parts.length > 1 ? parts[1].trim().toUpperCase() : "ASC"; String dbOrderField = getDbFieldName(clazz, orderField); if ("DESC".equals(direction)) { queryWrapper.orderByDesc(dbOrderField); } else { queryWrapper.orderByAsc(dbOrderField); } } } break; case ASC: queryWrapper.orderByAsc(fieldName); break; case RANGE: // 设置开始的值和结束的值 String[] attribute = queryWapperAnnotation.attribute(); String startRange = attribute[0]; // 声明属性描述对象 // getMethod = getMethod(startRange); // method = ReflectionUtils.findMethod(clazz, getMethod); method = getMethod(clazz, startRange); if (method != null) { Object val = method.invoke(obj); if (!ObjectUtils.isEmpty(val)) { queryWrapper.ge(fieldName, val); } } // 得到开始的属性值,通过反射设置属性值 // Field startRange = clazz.getDeclaredField(attribute[0]); // startRange.setAccessible(true); // Object val = startRange.get(obj); // 结束的属性值,通过反射设置属性值 String endRange = attribute[1]; // getMethod = getMethod(endRange); // 获取getter方法 // method = ReflectionUtils.findMethod(clazz, getMethod); method = getMethod(clazz, endRange); if (method != null) { Object val = method.invoke(obj); if (!ObjectUtils.isEmpty(val)) { queryWrapper.le(fieldName, val); } } // ---属性值查询结束的值---- // 通过传入的参数查询值 // 然后通过参数查询 Object val = param.get(attribute[0]); if (!ObjectUtils.isEmpty(val)) { queryWrapper.ge(fieldName, val); } // 然后通过参数查询 val = param.get(attribute[1]); if (!ObjectUtils.isEmpty(val)) { queryWrapper.le(fieldName, val); } break; default: break; } } } } } catch (Exception e) { e.printStackTrace(); } return queryWrapper; } /** * 获取数据库字段名(优先TableField.value,其次驼峰转下划线) */ private static String getDbFieldName(Class clazz, String fieldName) { if (StringUtils.isBlank(fieldName)) { return fieldName; } for (Field f : reflectForField(clazz)) { if (!f.getName().equals(fieldName)) { continue; } TableField attrTableField = AnnotationUtils.getAnnotation(f, TableField.class); if (attrTableField != null && attrTableField.exist() && !StringUtils.isBlank(attrTableField.value())) { return attrTableField.value(); } break; } return StringUtils.camelToUnderline(fieldName); } // 获取get方法 public static Method getMethod(Class clazz, String filedName) throws Exception { // String alpha = filedName.substring(0, 1).toUpperCase(); // String methodName = "get" + alpha + filedName.substring(1); // PropertyDescriptor p = new PropertyDescriptor(filedName, beanClass); // Method readMethod = p.getReadMethod(); return OgnlRuntime.getReadMethod(clazz, filedName); } }