Java精簡返回給前端的結果集


需求:

前端頁面需要展示三級菜單,后端返回結果集。問題在於,JavaBean中的屬性值比實際需要的數量多,為了節省后端傳遞給前端的流量,將不需要的屬性值設為null,這樣轉換為Json字符串的長度會小很多。

難點在於如何將id和parentid設置為null

數據結構要求如下:

 1 [
 2   {
 3     name:"一級菜單"
 4       menus:[ 
 5          {
 6           name:"二級菜單"
 7           menus:[
 8              {
 9                 name:"三級菜單"
10              },
11              .......
12           ]
13        },
14        .......
15       ]
16   },
17   .......
18 ]
接口文檔

數據庫中數據表:

 1 CREATE TABLE `tb_ad` (
 2   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
 3   `name` varchar(50) DEFAULT NULL COMMENT '廣告名稱',
 4   `position` varchar(50) DEFAULT NULL COMMENT '廣告位置',
 5   `start_time` datetime DEFAULT NULL COMMENT '開始時間',
 6   `end_time` datetime DEFAULT NULL COMMENT '到期時間',
 7   `status` char(1) DEFAULT NULL COMMENT '狀態',
 8   `image` varchar(100) DEFAULT NULL COMMENT '圖片地址',
 9   `url` varchar(100) DEFAULT NULL COMMENT 'URL',
10   `remarks` varchar(1000) DEFAULT NULL COMMENT '備注',
11   PRIMARY KEY (`id`)
12 )
數據表結構

對應的JavaBean如下:

 1 @Table(name="tb_category")
 2 public class Category implements Serializable{
 3 
 4     @Id
 5     private Integer id;//分類ID
 6 
 7     private String name;//分類名稱
 8 
 9     private Integer goodsNum;//商品數量
10 
11     private String isShow;//是否顯示
12 
13     private String isMenu;//是否導航
14 
15     private Integer seq;//排序
16 
17     private Integer parentId;//上級ID
18 
19     private Integer templateId;//模板ID
20     private List<Category> menus;
21         //省略get/set
22 
23 }
JavaBean

方式一,在雙層嵌套循環的過程中,在適當位置將id和parentid賦值為null。

優點,代碼編寫簡單,測試容易。缺點,對於非包裝類型無能為力,邏輯有點繞。

 1     public List<Category> findCategoryTree() {
 2         //1.查找所有需要顯示的category
 3         Example example = new Example(Category.class);
 4         Example.Criteria criteria = example.createCriteria();
 5         criteria.andEqualTo("isShow","1");
 6         example.setOrderByClause("seq");//排序
 7         List<Category> categories = categoryMapper.selectByExample(example);
 8         ArrayList<Category> parentList = new ArrayList<>();
 9         //2.通過遞歸的方式,給menus賦值
10         for (Category category : categories) {
11             //一級category
12             if(Objects.nonNull(category.getParentId())&&category.getParentId()==0){
13                 //清除一級目錄的parentId
14                 category.setParentId(null);
15                 parentList.add(category);
16             }
17             findChildren(categories,category);
18             category.setGoodsNum(null);
19             category.setIsMenu(null);
20             category.setIsShow(null);
21             category.setSeq(null);
22             category.setTemplateId(null);
23         }
24         return parentList;
25     }
26 
27     private void findChildren(List<Category> categories, Category category){
28         List<Category> list=new ArrayList<>();
29         for (Category category1 : categories) {
30             if(category.getId().equals(category1.getParentId())){
31                 //到此說明已經找到它的father,那么parentId已經沒有用了
32                 category1.setParentId(null);
33                 list.add(category1);
34             }
35         }
36         //到此說明已經找到它所有的children,那么id已經沒有用了
37         category.setId(null);
38         if(list.size()>0){
39             category.setMenus(list);
40         }
41     }
方式一

方式二,講樹狀的結果集轉為json字符串,利用正則表達式替換掉不需要的屬性,然后再將字符串轉為Object。

優點,對於非包裝類的屬性也適用,代碼重復利用性高。缺點,會生成多個字符串常量,占用內存稍高,正則表達式寫起來麻煩,不容易測試。

 1     public Object findCategoryTree() {
 2         //1.查找所有需要顯示的category
 3         Example example = new Example(Category.class);
 4         Example.Criteria criteria = example.createCriteria();
 5         criteria.andEqualTo("isShow","1");
 6         example.setOrderByClause("seq");//排序
 7         List<Category> categories = categoryMapper.selectByExample(example);
 8         ArrayList<Category> parentList = new ArrayList<>();
 9         //2.通過遞歸的方式,給menus賦值
10         for (Category category : categories) {
11             //一級category
12             if(Objects.nonNull(category.getParentId())&&category.getParentId()==0){
13                 //清除一級目錄的parentId
14                 //category.setParentId(null);
15                 parentList.add(category);
16             }
17             findChildren(categories,category);
18             category.setGoodsNum(null);
19             category.setIsMenu(null);
20             category.setIsShow(null);
21             category.setSeq(null);
22             category.setTemplateId(null);
23         }
24        //3.通過自定義方法將"id","parentId"屬性移除
25         ArrayList<String> attributes = new ArrayList<>();
26         attributes.add("id");
27         attributes.add("parentId");
28         return AttributeUtils.removeAttribute(parentList,attributes);
29     }
30 
31     private void findChildren(List<Category> categories, Category category){
32         List<Category> list=new ArrayList<>();
33         for (Category category1 : categories) {
34             if(category.getId().equals(category1.getParentId())){
35                 //到此說明已經找到它的father,那么parentId已經沒有用了
36                 //category1.setParentId(null);
37                 list.add(category1);
38             }
39         }
40         //到此說明已經找到它所有的children,那么id已經沒有用了
41         //category.setId(null);
42         if(list.size()>0){
43             category.setMenus(list);
44         }
45     }
方式二

自定義工具類

 1 public class AttributeUtils {
 2     public static <T> Object removeAttribute(List<T> list, List<String> attributeNames) {
 3         //1.將list轉為json字符串
 4         String jsonString = JSONObject.toJSONString(list);
 5         //2.刪除掉json字符串中相關屬性及屬性值
 6         for (String attributeName : attributeNames) {
 7             //元素在開頭
 8             String regex1 = "[^,]\""+attributeName+"\":*[^}]*?,";
 9             Pattern p1 = Pattern.compile(regex1);
10             Matcher m1 = p1.matcher(jsonString);
11             jsonString = m1.replaceAll("{");
12             //元素在尾部
13            String regex2 = ",\""+attributeName+"\":*[^{]*?}";
14             Pattern p2 = Pattern.compile(regex2);
15             Matcher m2 = p2.matcher(jsonString);
16             jsonString=m2.replaceAll("}");
17             //元素在中間
18             String regex3 = ",\""+attributeName+"\":*[^{]*?,";
19             Pattern p3 = Pattern.compile(regex3);
20             Matcher m3 = p3.matcher(jsonString);
21             jsonString=m3.replaceAll("");
22         }
23         Object parse = JSONObject.parse(jsonString);
24         return parse;
25     }
26 }
工具類

 


免責聲明!

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



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