需求:java
根據數據庫表,獲取省市縣的級連json數據,供前臺下拉列表。效果圖redis
表結構:數據庫
1 CREATE TABLE `bxqk_pe_area` ( 2 `id` int(11) NOT NULL AUTO_INCREMENT, 3 `fk_parent_id` int(11) DEFAULT NULL COMMENT '父id', 4 `name` varchar(20) NOT NULL COMMENT '名稱', 5 `flag_active` varchar(50) NOT NULL COMMENT '是否有效', 6 `type` int(11) NOT NULL COMMENT '類型(0:省、直轄市,1:市,2:區/縣)', 7 `is_delete` int(11) DEFAULT '0' COMMENT '是否刪除', 8 `create_user` varchar(50) DEFAULT NULL, 9 `create_time` date DEFAULT NULL, 10 `update_user` varchar(50) DEFAULT NULL, 11 `update_time` date DEFAULT NULL, 12 `note` varchar(50) DEFAULT NULL, 13 PRIMARY KEY (`id`), 14 KEY `index_type` (`type`), 15 KEY `fk_area_parent` (`fk_parent_id`), 16 KEY `fk_area_enum_const_active` (`flag_active`), 17 CONSTRAINT `fk_area_enum_const_active` FOREIGN KEY (`flag_active`) REFERENCES `enum_const` (`ID`), 18 CONSTRAINT `fk_area_parent` FOREIGN KEY (`fk_parent_id`) REFERENCES `bxqk_pe_area` (`id`) 19 ) ENGINE=InnoDB AUTO_INCREMENT=7017 DEFAULT CHARSET=utf8 COMMENT='地區表';
思路:兩種
先說好的一種(不論是效率仍是擴展性都是更好) json
直接上 代碼:數據結構說明在代碼後面緩存
1 /** 2 * 省市縣級json數據 3 * 4 * @return 5 */ 6 @LogAndNotice("省市縣級json數據") 7 public List<Map<String, Object>> listArea() { 8 List<Map<String, Object>> areas = (List<Map<String, Object>>) redisCacheService. 9 getFromCache(BxqkTeachingConstant.CACHE_KEY_AREAS); 10 if (CollectionUtils.isEmpty(areas)) { 11 areas = this.listAreasFromDataBase(new ArrayList<>()); 12 redisCacheService.putToCache(BxqkTeachingConstant.CACHE_KEY_AREAS, areas); 13 } 14 15 return areas; 16 } 17 18 /** 19 * 獲取地址信息數據 20 * 21 * @param areas 22 * @return 23 */ 24 @LogAndNotice("獲取地址信息數據") 25 private List<Map<String, Object>> listAreasFromDataBase(List<Map<String, Object>> areas) { 26 List<Map<String, Object>> allList = this.myGeneralDao. 27 getMapBySQL(" SELECT id, CONCAT(id, ',', type) value, name label, fk_parent_id parent " + 28 " FROM bxqk_pe_area ORDER BY type, CONVERT (NAME USING gbk) ASC "); 29 if (CollectionUtils.isEmpty(allList)) { 30 throw new ParameterIllegalException(); 31 } 32 Map<String, Object> areaMap = new HashMap<>(16); 33 allList.forEach(e -> { 34 String key = String.valueOf(e.get(BxqkTeachingConstant.ADDRESS_ID)); 35 String parentKey = String.valueOf(e.get(BxqkTeachingConstant.ADDRESS_PARENT)); 36 if (areaMap.containsKey(parentKey)) { 37 Map<String, Object> value = (Map<String, Object>) areaMap.get(parentKey); 38 value.putIfAbsent(BxqkTeachingConstant.ADDRESS_CHILDREN, new ArrayList<>()); 39 ((List<Map<String, Object>>)value.get(BxqkTeachingConstant.ADDRESS_CHILDREN)).add(e); 40 areaMap.put(key, e); 41 } else { 42 areaMap.put(key, e); 43 areas.add(e); 44 } 45 }); 46 47 return areas; 48 }
1 上述方法中的常量 2 BxqkTeachingConstant.java: 3 4 private String BxqkTeachingConstant.ADDRESS_ID = "id"; 5 private String ADDRESS_PARENT = "parent"; 6 private String ADDRESS_CHILDREN = "children"; 7 private String CACHE_KEY_AREAS = "areas";
完事。數據——>數據結構
設計數據結構:this
1 數據結構: 2 List<Map<String, Object>> allList 數據庫查出的全部數據 3 List<Map<String, Object>> areas 最終json數據 4 Map<String, Object> areaMap 遍歷時存放維持子父間關係的臨時map 5 6 數據結構關係以下(看懂的看,看不懂直接看代碼)——> 不會畫動圖 =-= 7 8 allList: 9 id fk_parent_id 10 1 null 11 2 null 12 3 1 13 4 1 14 5 3 15 6 5 16 17 維持關係的areaMap 18 map<area> areaMap: {key:id , value:map} 19 new Map{1, childrens} 20 new Map{3, childrens} 21 new Map{5, childrens} 22 new Map{4, childrens} 23 new Map{2, childrens} 24 new Map{3, childrens} 25 new Map{5, childrens} 26 27 new Map{4, childrens} 28 new Map{5, childrens} 29 30 結果集: 31 list<map> areas 32 new Map{1, childrens} 33 new Map{3, childrens} 34 new Map{5, childrens} 35 new Map{4, childrens} 36 new Map{2, childrens}
******************************************************************************************************************************************spa
第二種:(第一種看懂的這個直接pass掉!)設計
普通方法,現根據類型用3個集合分別存儲省市縣的信息,對3個list根據外鍵 fk_parent_id 父子關係遍歷便可code
代碼簡單,常量字符串再也不列出
1 /** 2 * 省市縣級聯json數據 3 * 4 * @return 5 */ 6 @LogAndNotice("省市縣級聯json數據") 7 public List<Map<String, Object>> listArea() { 8 List<Map<String, Object>> resultFromCache = (List<Map<String, Object>>) redisCacheService. 9 getFromCache(BxqkTeachingConstant.PARAM_CACHE_PROVINCES); 10 if (CollectionUtils.isNotEmpty(resultFromCache)) { 11 return resultFromCache; 12 } 13 List<Map<String, Object>> result = new ArrayList<>(); 14 List<Map<String, Object>> allList = this.myGeneralDao.getMapBySQL( 15 " SELECT id value, name label, fk_parent_id parent, type FROM bxqk_pe_area " + 16 " ORDER BY CONVERT (NAME USING gbk) ASC "); 17 if (CollectionUtils.isNotEmpty(allList)) { 18 List<Map<String, Object>> provinceList = new ArrayList(); 19 List<Map<String, Object>> cityList = new ArrayList(); 20 List<Map<String, Object>> countyList = new ArrayList(); 21 allList.forEach(e -> { 22 Map<String, Object> map = new HashMap<>(16); 23 if (String.valueOf(e.get(BxqkTeachingConstant.PARAM_ADDRESS_TYPE)) 24 .equals(BxqkTeachingConstant.PARAM_PROVINCE_TYPE_CODE)) { 25 provinceList.add(e); 26 } else if (String.valueOf(e.get(BxqkTeachingConstant.PARAM_ADDRESS_TYPE)) 27 .equals(BxqkTeachingConstant.PARAM_CITY_TYPE_CODE)) { 28 cityList.add(e); 29 } else if (String.valueOf(e.get(BxqkTeachingConstant.PARAM_ADDRESS_TYPE)) 30 .equals(BxqkTeachingConstant.PARAM_COUNTY_TYPE_CODE)) { 31 countyList.add(e); 32 } 33 }); 34 provinceList.forEach(e ->{ 35 Map<String, Object> provinceMap = new LinkedHashMap<>(); 36 provinceMap.put(BxqkTeachingConstant.PARAM_ADDRESS_VALUE, 37 e.get(BxqkTeachingConstant.PARAM_ADDRESS_VALUE) + "," + e.get(BxqkTeachingConstant.PARAM_ADDRESS_TYPE)); 38 provinceMap.put(BxqkTeachingConstant.PARAM_ADDRESS_LABEL, e.get(BxqkTeachingConstant.PARAM_ADDRESS_LABEL)); 39 40 List<Map<String, Object>> secondList = new ArrayList<>(); 41 cityList.forEach(c -> { 42 if (String.valueOf(e.get(BxqkTeachingConstant.PARAM_ADDRESS_VALUE)). 43 equals(String.valueOf(c.get(BxqkTeachingConstant.PARAM_ADDRESS_PARENT)))) { 44 Map<String, Object> cityMap = new LinkedHashMap<>(); 45 cityMap.put(BxqkTeachingConstant.PARAM_ADDRESS_VALUE, 46 c.get(BxqkTeachingConstant.PARAM_ADDRESS_VALUE) + "," + c.get(BxqkTeachingConstant.PARAM_ADDRESS_TYPE)); 47 cityMap.put(BxqkTeachingConstant.PARAM_ADDRESS_LABEL, c.get(BxqkTeachingConstant.PARAM_ADDRESS_LABEL)); 48 49 List<Map<String, Object>> levelThreeList = new ArrayList<>(); 50 countyList.forEach(t -> { 51 Map<String, Object> levelThreeMap = new LinkedHashMap<>(); 52 if (String.valueOf(c.get(BxqkTeachingConstant.PARAM_ADDRESS_VALUE)). 53 equals(String.valueOf(t.get(BxqkTeachingConstant.PARAM_ADDRESS_PARENT)))) { 54 levelThreeMap.put(BxqkTeachingConstant.PARAM_ADDRESS_VALUE, 55 t.get(BxqkTeachingConstant.PARAM_ADDRESS_VALUE) + "," + t.get(BxqkTeachingConstant.PARAM_ADDRESS_TYPE)); 56 levelThreeMap.put(BxqkTeachingConstant.PARAM_ADDRESS_LABEL, t.get(BxqkTeachingConstant.PARAM_ADDRESS_LABEL)); 57 levelThreeList.add(levelThreeMap); 58 } 59 }); 60 if (CollectionUtils.isNotEmpty(levelThreeList)) { 61 cityMap.put(BxqkTeachingConstant.PARAM_ADDRESS_CHILDREN, levelThreeList); 62 } 63 secondList.add(cityMap); 64 } 65 }); 66 provinceMap.put(BxqkTeachingConstant.PARAM_ADDRESS_CHILDREN, secondList); 67 result.add(provinceMap); 68 }); 69 redisCacheService.putToCache(BxqkTeachingConstant.PARAM_CACHE_PROVINCES, result); 70 return result; 71 } else { 72 throw new ParameterIllegalException(CommonConstant.PARAM_ERROR); 73 } 74 }
完事,記得都要放緩存呦→
記錄點滴生活...