package com.moral.common.util; import com.moral.common.bean.Constants; import com.moral.common.bean.PageBean; import lombok.extern.log4j.Log4j; import tk.mybatis.mapper.entity.Example; import javax.validation.constraints.NotNull; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URLDecoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Log4j public class ExampleUtil { private final static String SPLIT = "\\|"; private final static String OR = "_OR"; private final static String OR_SPLIT = OR+SPLIT; private final static String CRITERIA = "_CR"; private final static String CRITERIA_SPLIT = CRITERIA+SPLIT; private final static String CONDITION = "_CO"; private final static String CONDITION_SPLIT = CONDITION+SPLIT; private static Map criteriaMethodMap = new ConcurrentHashMap<>(); private static void setOrderByClause(Example example,String orderByClause) throws UnsupportedEncodingException, NoSuchFieldException { orderByClause = URLDecoder.decode(orderByClause,"UTF-8"); String[] orderBys = orderByClause.split(CRITERIA_SPLIT); for(String orderBy : orderBys){ String[] items = orderBy.split(CONDITION_SPLIT); if(items.length == 2){ String property = items[0]; String sort = items[1]; if(isPropertyOfClass(example.getEntityClass(),property)){ if("asc".equals(sort)){ example.orderBy(property).asc(); }else{ example.orderBy(property).desc(); } } } } } public static Example generateExample(Class clazz, PageBean page){ return generateExample(clazz,false,page); } public static Example generateExample(Class clazz, boolean isDelete, PageBean page) { Example example = null; try { String params = page.getQueryParams(); String orderByClause = page.getOrderByClause(); example = new Example(clazz); if(!StringUtils.isNullOrEmpty(orderByClause)){ setOrderByClause(example,orderByClause); } if(!StringUtils.isNullOrEmpty(params)){ params = URLDecoder.decode(params, "UTF-8"); loadCriterias(example,params); } if(!isDelete) { addDeletesToExample(example,clazz); } } catch (Exception ex) { log.error(ex.getMessage()); ex.printStackTrace(); } return example; } private static void loadCriterias(Example example,String params) throws InvocationTargetException, IllegalAccessException { if (params.startsWith(OR)) { String[] criteria = params.trim().split(OR_SPLIT); for (String criterion : criteria) { // criterion为null或""跳过 if(StringUtils.isNullOrEmpty(criterion)) { continue;}; Example.Criteria criteriaOfExample = example.or(); loadConditions(example,criteriaOfExample,criterion); } } } private static void loadConditions(Example example,Example.Criteria criteriaOfExample,String criterion) throws InvocationTargetException, IllegalAccessException { String[] conditions = criterion.trim().split(CRITERIA_SPLIT); for (String condition : conditions) { if (!StringUtils.isNullOrEmpty(condition)) { String[] conditionItems = condition.split(CONDITION_SPLIT); if (conditionItems != null && conditionItems.length > 1) { //方法名 String methodName = conditionItems[0]; //属性名 String propertyName = conditionItems[1]; //参数列表 List values = new ArrayList(); if (conditionItems.length > 2) { for (int index = 2; index < conditionItems.length; index++) { values.add(conditionItems[index]); } } Method method = getExampleMethod(methodName,values.size()+1); if (method != null && (methodName.equals("andCondition")||isPropertyOfClass(example.getEntityClass(), propertyName))) { invokeMethod(criteriaOfExample,method,propertyName,values); } else { log.warn(condition+" can't be executed as condition"); } } } } } private static boolean validatetParameters(@NotNull Method method,int len) { //前端传递propertyName参数为string类型 return method.getParameterCount() == (len+1) && method.getParameterTypes()[0].equals(String.class); } private static void invokeMethod(@NotNull Object obj,@NotNull Method method,@NotNull String propertyName,@NotNull List values) throws InvocationTargetException, IllegalAccessException { int len = values.size(); switch (len) { case 0: method.invoke(obj, propertyName); break; case 1: Object value = values.get(0) == "null" ? null : values.get(0); method.invoke(obj, propertyName,value); break; //between 查询 case 2: method.invoke(obj, propertyName, values.toArray()); break; //in 查询 default: method.invoke(obj, propertyName, values); break; } } ; /** * 增加删除条件过滤 * @param example */ private static void addDeletesToExample(Example example,Class clzz){ if(isPropertyOfClass(clzz,"isDelete")) { List criteriaList = example.getOredCriteria(); if(criteriaList!=null&&criteriaList.size()>0){ for(Example.Criteria cri : criteriaList){ boolean isHasIsDelete = false; for(Example.Criterion con : cri.getCriteria()){ if( con.getCondition().indexOf("is_delete") >-1) { isHasIsDelete = true; break; } } if( !isHasIsDelete) { cri.andNotEqualTo("isDelete", Constants.IS_DELETE_TRUE); } } }else { example.or().andNotEqualTo("isDelete",Constants.IS_DELETE_TRUE); } } } private static boolean isPropertyOfClass(Class clzz, String propertyName){ for(Field field : clzz.getDeclaredFields()) { if(field.getName().equals(propertyName)) { return true; } } return false; } private static Method getExampleMethod(String methodName, int paramCount) { String criteriaMethodKey = methodName+"_"+String.valueOf(paramCount); Method methodTemp = criteriaMethodMap.get(criteriaMethodKey); if(methodTemp==null) { Method[] methods = Example.Criteria.class.getMethods(); for (Method method : methods) { if(method.getName().equals(methodName)&&method.getParameterCount() == paramCount) { criteriaMethodMap.put(criteriaMethodKey,method); return method; } } } if(methodTemp==null || validatetParameters(methodTemp,paramCount)){ return null; } return methodTemp; } }