因為有時候需要根據前台的多個條件來過濾數據!因此需要根據是否有值以及當前值是以什么方式來過濾。這樣我們不可能一個一個值來判斷吧!這樣代碼就有些難看了!而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 }