fengxiang
2018-01-04 aa6c487c0eccd86311489e8a0ed641618e5b9105
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package com.moral.common.util;
 
import com.moral.common.bean.PageBean;
import lombok.extern.log4j.Log4j;
import tk.mybatis.mapper.entity.Example;
import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
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;
 
@Log4j
public class ExampleUtil {
    private final static String OR_SPLIT = "or\\|";
    private final static String CRITERIA_SPLIT = "\\|\\|\\|";
    private final static String CONDITION_SPLIT = "\\|\\|";
    private static Map<String, Method> criteriaMethodMap = null;
    private static void setOrderByClause(Example example,String orderByClause) throws UnsupportedEncodingException {
           orderByClause = URLDecoder.decode(orderByClause,"UTF-8");
           String[] orderBys = orderByClause.split(CRITERIA_SPLIT);
           for(String orderBy : orderBys){
               String[] items = orderBy.split(CONDITION_SPLIT);
               String property = items[0];
               String sort = items[1];
               if("asc".equals(sort)){
                   example.orderBy(property).asc();
               }else{
                   example.orderBy(property).desc();
               }
           }
    }
    public static Example generateExample(Class clzz, PageBean page) {
        Example example = null;
        try {
            String params = page.getQueryParams();
            String orderByClause = page.getOrderByClause();
            example = new Example(clzz);
            if(!StringUtils.isNullOrEmpty(orderByClause)){
                setOrderByClause(example,orderByClause);
            }
            if(StringUtils.isNullOrEmpty(params)){ return example;}
            params = URLDecoder.decode(params, "UTF-8");
            if (!StringUtils.isNullOrEmpty(params) && params.startsWith("or|")) {
                String[] criteria = params.trim().split(OR_SPLIT);
                for (String criterion : criteria) {
                    Example.Criteria criteriaOfExample = null;
                    if (!StringUtils.isNullOrEmpty(criterion)) {
                        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];
                                    Method method = getMethod(methodName);
                                    if (method != null && isPropertyOfClass(clzz, propertyName)) {
                                        List values = new ArrayList<Object>();
                                        if (conditionItems.length > 2) {
                                            for (int index = 2; index < conditionItems.length; index++) {
                                                values.add(conditionItems[index]);
                                            }
                                        }
                                        //经过所有验证后,才产生 or 条件组
                                        if(criteriaOfExample == null){
                                            criteriaOfExample = example.or();
                                        }
                                        invokeMethod(criteriaOfExample,method,propertyName,values);
                                    }
 
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            ex.printStackTrace();
        }
        return example;
    }
 
    private static void invokeMethod(Object obj, Method method,String propertyName,List values) throws InvocationTargetException, IllegalAccessException {
        int len = values.size();
        switch (len) {
            case 0:
                if(method.getParameterCount()==1) {
                    method.invoke(obj, propertyName);
                }
                break;
            case 1:
 
                if(method.getParameterCount()==2){
                    method.invoke(obj,propertyName,values.get(0));
                }
                break;
            //between 查询
            case 2:
                if(method.getParameterCount()==3){
                    method.invoke(obj,propertyName,values.toArray());
                }
                break;
            //in 查询
            default:
                if(method.getParameterCount()==2){
                method.invoke(obj,propertyName,values);
                }
                break;
        }
    }
 
    ;
 
    private static boolean isPropertyOfClass(Class clzz, String propertyName) throws NoSuchFieldException {
        return clzz.getDeclaredField(propertyName) != null;
    }
 
    private static Method getMethod(String methodName) {
        if (criteriaMethodMap == null) {
            criteriaMethodMap = new HashMap<>();
            Method[] methods = Example.Criteria.class.getMethods();
            for (Method m : methods) {
                Method method = criteriaMethodMap.get(m.getName());
                //重载函数存储参数最长的
                if (method==null||m.getParameterTypes().length>method.getParameterTypes().length){
                    criteriaMethodMap.put(m.getName(),m);
                }
            }
        }
        return criteriaMethodMap.get(methodName);
    }
}