生成jFinal的動態條件查詢語句的工具類


因為有時候需要根據前台的多個條件來過濾數據!因此需要根據是否有值以及當前值是以什么方式來過濾。這樣我們不可能一個一個值來判斷吧!這樣代碼就有些難看了!而jFinal也沒有提供這樣的方法,而網上的一些解決方法感覺不太好用麻煩而且不夠靈活!基於這個考慮我就自己寫了一個工具類!目前來說用着還挺方便的!如果有什么不對或者改進的地方請指正,大家共同進步!

  1 /**
  2  * 用於生成JFinal的SQL查詢語句<br>
  3  * 類名稱:Conditions<br>
  4  * 創建人:yangxp<br>
  5  * 創建時間:2014-1-19 上午11:22:26<br>
  6  * 
  7  * @version v1.0.9
  8  * 
  9  */
 10 public class Conditions {
 11     static Logger log = Logger.getLogger(Conditions.class);
 12 
 13     public static final String EQUAL = "EQUAL"; // 相等
 14 
 15     public static final String NOT_EQUAL = "NOT_EQUAL"; // 不相等
 16 
 17     public static final String LESS_THEN = "LESS_THEN"; // 小於
 18 
 19     public static final String LESS_EQUAL = "LESS_EQUAL"; // 小於等於
 20 
 21     public static final String GREATER_EQUAL = "GREATER_EQUAL"; // 大於等於
 22 
 23     public static final String GREATER_THEN = "GREATER_THEN"; // 大於
 24 
 25     public static final String FUZZY = "FUZZY"; // 模糊匹配 %xxx%
 26 
 27     public static final String FUZZY_LEFT = "FUZZY_LEFT"; // 左模糊 %xxx
 28 
 29     public static final String FUZZY_RIGHT = "FUZZY_RIGHT"; // 右模糊 xxx%
 30 
 31     public static final String NOT_EMPTY = "NOT_EMPTY"; // 不為空值的情況
 32 
 33     public static final String EMPTY = "EMPTY"; // 空值的情況
 34 
 35     public static final String IN = "IN"; // 在范圍內
 36 
 37     public static final String NOT_IN = "NOT_IN"; // 不在范圍內
 38 
 39     // 用於接收SQL語句
 40     private ThreadLocal<String> sql = new ThreadLocal<String>();
 41 
 42     // 用於接收參數數組
 43     private ThreadLocal<ArrayList<Object>> paramList = new ThreadLocal<ArrayList<Object>>();
 44 
 45     // 用於存放設置的條件
 46     private ThreadLocal<Map<String, Object[]>> conditionMap = new ThreadLocal<Map<String, Object[]>>();
 47 
 48     // 用於存放需要排除的字段
 49     private ThreadLocal<Map<String, String>> excludeFieldMap = new ThreadLocal<Map<String, String>>();
 50 
 51     // 構造方法(表示沒有設置查詢類型的字段全部按照等於來處理)
 52     public Conditions() {
 53         conditionMap.set(new HashMap<String, Object[]>());
 54         excludeFieldMap.set(new HashMap<String, String>());
 55     }
 56 
 57     // 構造方法(設置后表示字段所有的查詢方式按照設置類型來處理,除非后面針對字段的重新設置)
 58     public Conditions(String type) {
 59         Map<String, Object[]> map = new HashMap<String, Object[]>();
 60         map.put("GLOBALTYPE", new String[] { type });
 61         conditionMap.set(map);
 62         excludeFieldMap.set(new HashMap<String, String>());
 63     }
 64 
 65     /***************************************************************************
 66      * 設置字段的查詢類型
 67      * 
 68      * @param QueryType
 69      *            查詢類型
 70      * @param fieldName
 71      *            字段名稱數組
 72      */
 73     public void setFiledQuery(String QueryType, String... filedName) {
 74         if (StringUtils.isNotBlank(QueryType) && !Common.isNullOrEmpty(filedName)) {
 75             Map<String, Object[]> map = conditionMap.get();
 76             map.put(QueryType, filedName);
 77             conditionMap.set(map);
 78         }
 79     }
 80 
 81     /***************************************************************************
 82      * 設置需要排除的字段
 83      * 
 84      * setexcludeField<br>
 85      * 
 86      * @param 參數說明
 87      * @return 返回對象
 88      * @Exception 異常對象
 89      * 
 90      */
 91     public void setExcludeField(String... filedName) {
 92         if (!Common.isNullOrEmpty(filedName)) {
 93             Map<String, String> map = excludeFieldMap.get();
 94             for (String str : filedName) {
 95                 map.put(str, str);
 96             }
 97             excludeFieldMap.set(map);
 98         }
 99     }
100 
101     /***************************************************************************
102      * 查詢空值或者不為空值的情況 setNullFieldQuery
103      * 
104      * @param 參數說明
105      * @return 返回對象
106      * @Exception 異常對象
107      */
108     public void setNullOrNotNullFieldQuery(String QueryType, String... filedName) {
109         if (StringUtils.isNotBlank(QueryType) && !Common.isNullOrEmpty(filedName)) {
110             if (!NOT_EMPTY.equals(QueryType) && !EMPTY.equals(QueryType)) {
111                 log.error("空值或者非空查詢的類型只能為:EMPTY、NOT_EMPTY");
112                 throw new RuntimeException("空值或者非空查詢的類型只能為:EMPTY、NOT_EMPTY");
113             }
114             Map<String, Object[]> map = conditionMap.get();
115             map.put(QueryType, filedName);
116             conditionMap.set(map);
117         }
118     }
119 
120     /***************************************************************************
121      * <b>傳值查詢</b><br>
122      * 注:如果QueryType為<b>in</b>或者<b>not in</b>那么filedValue必須為一個list對象
123      * 
124      * @param QueryType
125      *            查詢類型
126      * @param fieldName
127      *            字段名稱
128      * @param filedValue
129      *            字段值
130      */
131     public void setValueQuery(String QueryType, String fieldName, Object filedValue) {
132         if (StringUtils.isNotBlank(QueryType) && StringUtils.isNotBlank(fieldName) && !Common.isNullOrEmpty(filedValue)) {
133             Object[] param = new Object[2];
134             param[0] = fieldName; // 字段名
135             param[1] = filedValue;// 字段值
136             Map<String, Object[]> map = conditionMap.get();
137             map.put(QueryType + "#" + fieldName, param);// 避免類型重復被覆蓋掉就加上字段名
138             conditionMap.set(map);
139         }
140     }
141 
142     /***************************************************************************
143      * 用於生成SQL條件語句不帶別名
144      * 
145      * @param modelClass
146      *            必須繼承於Model
147      */
148     public void modelToCondition(Model<?> modelClass) {
149         modelToCondition(modelClass, null);
150     }
151 
152     /***************************************************************************
153      * 用於生成SQL條件語句不帶別名
154      * 
155      * @param RecordClass
156      *            必須是一個Record類
157      */
158     public void recordToCondition(Record recordClass) {
159         recordToCondition(recordClass, null);
160     }
161 
162     /***************************************************************************
163      * 用於生成SQL條件語句帶別名
164      * 
165      * @param modelClass
166      *            必須繼承於Model
167      * @param alias
168      *            別名
169      */
170     public void modelToCondition(Model<?> modelClass, String alias) {
171         alias = StringUtils.isNotBlank(alias) ? alias + "." : "";
172         if (modelClass != null) {
173             // 所有的字段
174             String[] fieldNames = modelClass.getAttrNames();
175             // 字段名和值的map集合
176             Map<String, Object> valueMap = Common.modelToMap(modelClass);
177 
178             // 構建查詢條件
179             buildCondition(alias, fieldNames, valueMap);
180         } else {
181             if (!conditionMap.get().isEmpty()) {
182                 buildCondition(alias, new String[] {}, new HashMap<String, Object>());
183             } else {
184                 sql.set("");
185                 paramList.set(new ArrayList<Object>());
186             }
187         }
188     }
189 
190     /***************************************************************************
191      * 用於生成SQL條件語句不帶別名
192      * 
193      * @param RecordClass
194      *            必須是一個Record類
195      * @param alias
196      *            別名
197      */
198     public void recordToCondition(Record recordClass, String alias) {
199         // 別名
200         alias = StringUtils.isNotBlank(alias) ? alias + "." : "";
201         if (recordClass != null) {
202             // 所有的字段
203             String[] fieldNames = recordClass.getColumnNames();
204             // 字段名和值的map集合
205             Map<String, Object> valueMap = Common.recordToMap(recordClass);
206 
207             // 構建查詢條件
208             buildCondition(alias, fieldNames, valueMap);
209         } else {
210             if (!conditionMap.get().isEmpty()) {
211                 buildCondition(alias, new String[] {}, new HashMap<String, Object>());
212             } else {
213                 sql.set("");
214                 paramList.set(new ArrayList<Object>());
215             }
216         }
217     }
218 
219     /***************************************************************************
220      * 構建條件語句
221      * 
222      * @param resultMap
223      *            用於返回結果的map
224      * @param alias
225      *            別名
226      * @param fieldNames
227      *            所有查詢的字段名稱
228      * @param valueMap
229      *            所有的值的map
230      */
231     private void buildCondition(String alias, String[] fieldNames, Map<String, Object> valueMap) {
232         try {
233             // 構建條件前先清空變量
234             sql.set("");
235             paramList.set(new ArrayList<Object>());
236             // 用於存放參數列表
237             ArrayList<Object> paramArrayList = new ArrayList<Object>();
238             StringBuilder sb = new StringBuilder();
239             // 所有的字段名稱
240             Map<String, String> usedFieldMap = new HashMap<String, String>();
241             if (!conditionMap.get().isEmpty()) {
242                 for (Entry<String, Object[]> map : conditionMap.get().entrySet()) {
243                     String queryType = map.getKey();
244                     Object[] array = map.getValue();
245                     if (queryType.indexOf("#") > 0) {// 傳值查詢
246                         String fieldQueryType = queryType.split("#")[0];
247                         String fieldName = array[0] != null ? array[0].toString() : "";
248                         Object fieldValue = array[1];
249 
250                         // 將設置過的字段保存到數組中
251                         usedFieldMap.put(fieldName, fieldName);
252                         // 構建SQL語句
253                         buildSQL(sb, fieldQueryType, fieldName, fieldValue, alias, paramArrayList);
254                     } else {// 字段查詢
255                         if (!"GLOBALTYPE".equals(queryType)) {
256                             for (Object field : array) {
257                                 String filedName = field != null ? field.toString() : "";
258                                 if (!excludeFieldMap.get().containsKey(filedName)) {
259                                     Object fieldValue = valueMap.get(filedName);
260                                     // 將設置過的字段保存到數組中
261                                     usedFieldMap.put(filedName, filedName);
262                                     // 構建查詢語句
263                                     buildSQL(sb, queryType, filedName, fieldValue, alias, paramArrayList);
264                                 }
265                             }
266                         }
267                     }
268                 }
269             }
270             // 對沒有設置條件的字段進行查詢類型設置
271             String queryType = EQUAL;
272             if (conditionMap.get().containsKey("GLOBALTYPE")) {
273                 String[] typeArray = (String[]) conditionMap.get().get("GLOBALTYPE");
274                 queryType = typeArray[0];
275             }
276             // 對未使用過的字段進行build
277             for (String field : fieldNames) {
278                 if (!usedFieldMap.containsKey(field)) {
279                     Object fieldValue = valueMap.get(field);
280                     // 構建查詢語句
281                     buildSQL(sb, queryType, field, fieldValue, alias, paramArrayList);
282                 }
283             }
284 
285             // 合並傳入的參數到參數對象中
286             sql.set(sb.toString());
287             paramList.set(paramArrayList);
288             conditionMap.set(new HashMap<String, Object[]>());// 清空本次的條件map
289             excludeFieldMap.set(new HashMap<String, String>());// 清空本次的排除字段
290         } catch (Exception e) {
291             log.error("Conditions構建SQL語句出現錯誤,請仔細檢查!",e);
292             e.printStackTrace();
293         }
294     }
295 
296     /***************************************************************************
297      * 構建SQL語句
298      * 
299      * @param sb
300      *            用於拼接SQL語句
301      * @param queryType
302      *            查詢類型
303      * @param fieldName
304      *            字段名稱
305      * @param fieldValue
306      *            字段值
307      * @param alias
308      *            別名
309      * @return
310      */
311     @SuppressWarnings("unchecked")
312     private void buildSQL(StringBuilder sb, String queryType, String fieldName, Object fieldValue, String alias, ArrayList<Object> params) {
313         // 非空的時候進行設置
314         if (!Common.isNullOrEmpty(fieldValue) && !Common.isNullOrEmpty(fieldName)) {
315             if (EQUAL.equals(queryType)) {
316                 sb.append(" and " + alias + fieldName + " = ? ");
317                 params.add(fieldValue);
318             } else if (NOT_EQUAL.equals(queryType)) {
319                 sb.append(" and " + alias + fieldName + " <> ? ");
320                 params.add(fieldValue);
321             } else if (LESS_THEN.equals(queryType)) {
322                 sb.append(" and " + alias + fieldName + " < ? ");
323                 params.add(fieldValue);
324             } else if (LESS_EQUAL.equals(queryType)) {
325                 sb.append(" and " + alias + fieldName + " <= ? ");
326                 params.add(fieldValue);
327             } else if (GREATER_THEN.equals(queryType)) {
328                 sb.append(" and " + alias + fieldName + " > ? ");
329                 params.add(fieldValue);
330             } else if (GREATER_EQUAL.equals(queryType)) {
331                 sb.append(" and " + alias + fieldName + " >= ? ");
332                 params.add(fieldValue);
333             } else if (FUZZY.equals(queryType)) {
334                 sb.append(" and " + alias + fieldName + " like ? ");
335                 params.add("%" + fieldValue + "%");
336             } else if (FUZZY_LEFT.equals(queryType)) {
337                 sb.append(" and " + alias + fieldName + " like ? ");
338                 params.add("%" + fieldValue);
339             } else if (FUZZY_RIGHT.equals(queryType)) {
340                 sb.append(" and " + alias + fieldName + " like ? ");
341                 params.add(fieldValue + "%");
342             } else if (IN.equals(queryType)) {
343                 try {
344                     List list = (List) fieldValue;
345                     StringBuffer instr = new StringBuffer();
346                     sb.append(" and " + alias + fieldName + " in (");
347                     for (Object obj : list) {
348                         instr.append(StringUtils.isNotBlank(instr) ? ",?" : "?");
349                         params.add(obj);
350                     }
351                     sb.append(instr + ") ");
352                 } catch (Exception e) {
353                     throw new RuntimeException("使用IN條件的時候傳入的值必須是個List對象,否則將會轉換出錯!例如將 in('1','2','3')中的'1','2','3'分為三個分別添加到List中做為值傳入.",e);
354                 }
355             } else if (NOT_IN.equals(queryType)) {
356                 try {
357                     List list = (List) fieldValue;
358                     StringBuffer instr = new StringBuffer();
359                     sb.append(" and " + alias + fieldName + " not in (");
360                     for (Object obj : list) {
361                         instr.append(StringUtils.isNotBlank(instr) ? ",?" : "?");
362                         params.add(obj);
363                     }
364                     sb.append(instr + ") ");
365                 } catch (Exception e) {
366                     throw new RuntimeException("使用NOT IN條件的時候傳入的值必須是個List對象,否則將會轉換出錯!例如將 not in('1','2','3')中的'1','2','3'分為三個分別添加到List中做為值傳入.",e);
367                 }
368             }
369         } else {
370             if (EMPTY.equals(queryType)) {
371                 sb.append(" and " + alias + fieldName + " is null ");
372             } else if (NOT_EMPTY.equals(queryType)) {
373                 sb.append(" and " + alias + fieldName + " is not null ");
374             }
375         }
376     }
377 
378     public String getSql() {
379         return sql.get();
380     }
381 
382     public List<Object> getParamList() {
383         return paramList.get();
384     }
385 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM