CustomerSpecs.java
3.08 KB
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
package com.bsth.entity.search;
import com.bsth.entity.search.exception.UnrecognizableSearchSymbolException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.*;
import java.lang.reflect.Method;
import java.util.*;
/**
*
* @ClassName: CustomerSpecs
* @Description: 用于动态条件查询的Specification
* @author PanZhao
* @date 2016年3月16日 下午4:05:22
*
* @param <T>
*/
public class CustomerSpecs<T> implements Specification<T> {
Logger logger = LoggerFactory.getLogger(this.getClass());
private Map<String, Object> map;
// 查询操作符
private static Set<String> eSet;
static {
eSet = new TreeSet<String>();
for (SearchOperator s : SearchOperator.values()) {
eSet.add(s.toString());
}
}
private static Class<PredicatesBuilder> preBuilderClazz = PredicatesBuilder.class;
private static Class<CriteriaBuilder> cBuilderClazz = CriteriaBuilder.class;
private static Class<Object> objClazz = Object.class;
// 查询参数分隔符
public static final String separator = "_";
/**
* 构造函数
*
* @param map
*/
public CustomerSpecs(Map<String, Object> map) {
this.map = map;
}
@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object value = entry.getValue();
String[] searchs = StringUtils.split(entry.getKey(), separator);
if (null == searchs || searchs.length < 2)
continue;
// 值为空的不参与查询
if (value == null || (value instanceof String && value.equals("")))
continue;
// 如果是布尔值,转换,限定 'true','false' 字符串
if ("true".equals(value)) {
value = Boolean.TRUE;
}
if ("false".equals(value)) {
value = Boolean.FALSE;
}
try {
if(!eSet.contains(searchs[1]))
throw new UnrecognizableSearchSymbolException(searchs[1]);
// 根据操作符调用对应静态函数
Method method = preBuilderClazz.getMethod(searchs[1],
cBuilderClazz, Path.class, objClazz);
Predicate predicate = (Predicate) method.invoke(null, cb,
createPath(root, searchs[0]), value);
predicates.add(predicate);
} catch (Exception e) {
logger.error("Specification search error.", e);
}
}
Predicate[] pre = new Predicate[predicates.size()];
return query.where(predicates.toArray(pre)).getRestriction();
}
/**
* 生成Path
* @param root
* @param field
* @return
*/
public Path<T> createPath(Root<T> root, String field){
Path<T> p = null;
if(field.indexOf(".") == -1)
p = root.get(field);
else{
String[] fs = field.split("\\.");
p = root.get(fs[0]);
for(int i = 1; i < fs.length; i ++){
p = p.get(fs[i]);
}
}
return p;
}
}