10
10
import cn .veasion .db .utils .FieldUtils ;
11
11
12
12
import java .lang .reflect .Field ;
13
+ import java .text .SimpleDateFormat ;
13
14
import java .util .Arrays ;
14
15
import java .util .Collection ;
16
+ import java .util .Date ;
15
17
import java .util .HashMap ;
16
18
import java .util .HashSet ;
17
19
import java .util .Iterator ;
18
20
import java .util .Map ;
19
21
import java .util .Objects ;
20
22
import java .util .Set ;
23
+ import java .util .regex .Pattern ;
21
24
22
25
/**
23
26
* QueryCriteriaConvert
27
30
*/
28
31
public class QueryCriteriaConvert {
29
32
33
+ public static final Pattern FIELD_PATTERN = Pattern .compile ("[_0-9a-zA-Z]+" );
34
+
30
35
private Object object ;
31
36
private EntityQuery query ;
32
37
private JoinCriteria [] array ;
@@ -69,6 +74,7 @@ public Map<Class<?>, EntityQuery> getJoinClassMap() {
69
74
return joinClassMap ;
70
75
}
71
76
77
+ @ SuppressWarnings ("unchecked" )
72
78
private void handleFilters () {
73
79
JoinCriteriaMulti joinCriteriaMulti = object .getClass ().getAnnotation (JoinCriteriaMulti .class );
74
80
if (joinCriteriaMulti != null ) {
@@ -77,53 +83,100 @@ private void handleFilters() {
77
83
initJoinClassMap ();
78
84
Map <String , Field > fields = FieldUtils .fields (object .getClass ());
79
85
for (Field field : fields .values ()) {
80
- QueryCriteria annotation = field .getAnnotation (QueryCriteria .class );
81
- if (annotation == null ) {
86
+ QueryCriteria queryCriteria = field .getAnnotation (QueryCriteria .class );
87
+ AutoCriteria autoCriteria = field .getAnnotation (AutoCriteria .class );
88
+ if (queryCriteria == null && autoCriteria == null ) {
82
89
continue ;
83
90
}
84
91
Object value = FieldUtils .getValue (object , field .getName (), true );
85
92
if (value == null ) {
86
93
continue ;
87
94
}
88
- boolean skipEmpty = annotation .skipEmpty ();
89
- if (skipEmpty ) {
90
- if (value instanceof String && "" .equals (value )) {
91
- continue ;
92
- } else if (value instanceof Collection && ((Collection <?>) value ).isEmpty ()) {
93
- continue ;
94
- } else if (value instanceof Object [] && ((Object []) value ).length == 0 ) {
95
- continue ;
96
- }
95
+ if (queryCriteria != null ) {
96
+ handleQueryCriteria (field , queryCriteria , value );
97
+ } else if (value instanceof Map ) {
98
+ handleAutoCriteria (autoCriteria , (Map <String , Object >) value );
99
+ } else {
100
+ handleAutoCriteria (autoCriteria , new HashMap <String , Object >() {{
101
+ put (field .getName (), value );
102
+ }});
97
103
}
98
- String fieldName = "" .equals (annotation .field ()) ? field .getName () : annotation .field ();
99
- Operator operator = annotation .value ();
100
- Class <?> relationClass = annotation .relation ();
104
+ }
105
+ }
101
106
107
+ private void handleAutoCriteria (AutoCriteria annotation , Map <String , Object > filters ) {
108
+ Class <?> relationClass = annotation .relation ();
109
+ for (Map .Entry <String , Object > entry : filters .entrySet ()) {
110
+ String key = entry .getKey ();
111
+ Object value = entry .getValue ();
112
+ if (value == null ) {
113
+ continue ;
114
+ }
115
+ if (annotation .skipEmpty () && isEmpty (value )) {
116
+ return ;
117
+ }
118
+ if (!FIELD_PATTERN .matcher (key ).matches ()) {
119
+ throw new FilterException ("非法字段:" + key );
120
+ }
102
121
if (relationClass != Void .class ) {
103
122
checkJoin (relationClass );
104
123
}
124
+ Operator operator = Operator .EQ ;
125
+ if (value instanceof Collection || value instanceof Object []) {
126
+ operator = Operator .IN ;
127
+ } else if (key .startsWith ("start_" )) {
128
+ key = key .substring (6 );
129
+ operator = Operator .GTE ;
130
+ } else if (key .startsWith ("end_" )) {
131
+ key = key .substring (4 );
132
+ operator = Operator .LTE ;
133
+ } else if (value instanceof String &&
134
+ (String .valueOf (value ).startsWith ("%" ) || String .valueOf (value ).endsWith ("%" ))) {
135
+ operator = Operator .LIKE ;
136
+ }
137
+ if (value instanceof Date ) {
138
+ value = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ).format ((Date ) value );
139
+ }
140
+ Filter filter = getFilter (key , operator , value );
141
+ if (relationClass != Void .class ) {
142
+ filter .fieldAs (joinClassMap .get (relationClass ).getTableAs ());
143
+ }
144
+ query .addFilter (filter );
145
+ }
146
+ }
105
147
106
- String [] orFields = annotation .orFields ();
107
- if (orFields .length > 0 ) {
108
- query .addFilter (Filter .leftBracket ());
109
- for (int i = 0 ; i < orFields .length ; i ++) {
110
- Filter filter = getFilter (orFields [i ], operator , value );
111
- if (relationClass != Void .class ) {
112
- filter .fieldAs (joinClassMap .get (relationClass ).getTableAs ());
113
- }
114
- query .addFilter (filter );
115
- if (i < orFields .length - 1 ) {
116
- query .addFilter (Filter .or ());
117
- }
118
- }
119
- query .addFilter (Filter .rightBracket ());
120
- } else {
121
- Filter filter = getFilter (fieldName , operator , value );
148
+ private void handleQueryCriteria (Field field , QueryCriteria annotation , Object value ) {
149
+ if (annotation .skipEmpty () && isEmpty (value )) {
150
+ return ;
151
+ }
152
+ String fieldName = "" .equals (annotation .field ()) ? field .getName () : annotation .field ();
153
+ Operator operator = annotation .value ();
154
+ Class <?> relationClass = annotation .relation ();
155
+
156
+ if (relationClass != Void .class ) {
157
+ checkJoin (relationClass );
158
+ }
159
+
160
+ String [] orFields = annotation .orFields ();
161
+ if (orFields .length > 0 ) {
162
+ query .addFilter (Filter .leftBracket ());
163
+ for (int i = 0 ; i < orFields .length ; i ++) {
164
+ Filter filter = getFilter (orFields [i ], operator , value );
122
165
if (relationClass != Void .class ) {
123
166
filter .fieldAs (joinClassMap .get (relationClass ).getTableAs ());
124
167
}
125
168
query .addFilter (filter );
169
+ if (i < orFields .length - 1 ) {
170
+ query .addFilter (Filter .or ());
171
+ }
126
172
}
173
+ query .addFilter (Filter .rightBracket ());
174
+ } else {
175
+ Filter filter = getFilter (fieldName , operator , value );
176
+ if (relationClass != Void .class ) {
177
+ filter .fieldAs (joinClassMap .get (relationClass ).getTableAs ());
178
+ }
179
+ query .addFilter (filter );
127
180
}
128
181
}
129
182
@@ -170,6 +223,20 @@ private void checkJoin(Class<?> joinClass) {
170
223
} while (joinClass != Void .class && !joined .contains (joinClass ));
171
224
}
172
225
226
+ private boolean isEmpty (Object value ) {
227
+ if (value == null ) {
228
+ return true ;
229
+ }
230
+ if (value instanceof String && "" .equals (value )) {
231
+ return true ;
232
+ } else if (value instanceof Collection && ((Collection <?>) value ).isEmpty ()) {
233
+ return true ;
234
+ } else if (value instanceof Object [] && ((Object []) value ).length == 0 ) {
235
+ return true ;
236
+ }
237
+ return false ;
238
+ }
239
+
173
240
public static Filter getFilter (String field , Operator operator , Object value ) {
174
241
if (Operator .EQ .equals (operator )) {
175
242
return Filter .eq (field , value );
@@ -200,6 +267,16 @@ public static Filter getFilter(String field, Operator operator, Object value) {
200
267
throw new FilterException (field + " 字段 Operator.IN 类型必须是集合或者数组" );
201
268
}
202
269
} else if (Operator .LIKE .equals (operator )) {
270
+ if (value instanceof String ) {
271
+ String str = (String ) value ;
272
+ if (str .startsWith ("%" ) && str .endsWith ("%" )) {
273
+ return Filter .like (field , str .substring (1 , str .length () - 1 ));
274
+ } else if (str .startsWith ("%" )) {
275
+ return Filter .likeLeft (field , str .substring (1 ));
276
+ } else if (str .endsWith ("%" )) {
277
+ return Filter .likeRight (field , str .substring (0 , str .length () - 1 ));
278
+ }
279
+ }
203
280
return Filter .like (field , value );
204
281
} else if (Operator .BETWEEN .equals (operator )) {
205
282
if (value instanceof Collection ) {
0 commit comments