天天看點

Java 将有父子關系的資料轉換成樹形結構資料

一、資料庫父子結構資料設計

    大部分采用 parentId的形式來存儲父id,并且隻存儲父id,祖父Id不存儲。也可以添加存儲層級級别或者層級關系等字段。

CREATE TABLE `t_resource` (
  `id` varchar(255) NOT NULL COMMENT '主鍵',
  `parent_id` varchar(255) DEFAULT NULL COMMENT '父ID',
  `name` varchar(255) DEFAULT NULL COMMENT '名稱',
  `url` varchar(255) DEFAULT NULL COMMENT '資源url',
  `level` varchar(255) DEFAULT NULL COMMENT '層級級别',
  `decode` varchar(255) DEFAULT NULL COMMENT '層級ID的關系,用”_“分割',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
           
Java 将有父子關系的資料轉換成樹形結構資料

二、将有父子關系的資料轉換成樹形結構資料

   mapper層擷取資料庫資料和 controller層處理很簡單,将有父子關系的資料轉換成樹形結構資料交給 service層處理。

@PostMapping("/getMuneTree")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> getMuneTree(){
        Map<String, Object> map = new HashMap<>();
        map.put("menuList", resourceDOService.getMuneTree());
        return ResponseEntity.ok(map);
    }
           
Java 将有父子關系的資料轉換成樹形結構資料

    1、方式一:遞歸:從樹的最頂級擷取子級,然後子級擷取其子級。

          傳回時,需要哪些字段值就添加哪些字段值到 map中。結果圖如上

/**
     * 将有父子關系的資料轉換成樹形結構資料
     *
     * @return 最終的樹狀結構的集合資料
     */
    @Override
    public List<Map<String, Object>> getMuneTree() {
        // 擷取資料庫中帶有有父子關系的資料
        List<ResourceDO> data = resourceDOMapper.selectAll();
        
        //建立一個List集合來存放最終的樹狀結構資料
        List<Map<String, Object>> menuList = new ArrayList<>();
        // 先存入最頂級的樹(0代表沒有父級,即最頂級),然後通過最頂級的id遞歸擷取子級
        for (ResourceDO entity : data) {
            Map<String, Object> map = new HashMap<>();
            if ("0".equals(entity.getParentId())) {
                map.put("id", entity.getId());
                map.put("parentId", entity.getParentId());
                map.put("name", entity.getName());
                map.put("children", getChildren(data, entity.getId()));
                menuList.add(map);
            }
        }
        return menuList;
    }

    /**
     * 遞歸處理:通過id擷取子級,查詢子級下的子級
     *
     * @param data 資料庫的原始資料
     * @param id   主id
     * @return  該id下得子級
     */
    public List<Map<String, Object>> getChildren(List<ResourceDO> data, String id) {
        List<Map<String, Object>> list = new ArrayList<>();
        if (data == null || data.size() == 0 || id == null) {
            return list;
        }
        for (ResourceDO entity : data) {
            Map<String, Object> map = new HashMap<>();
            //如果本級id與資料的父id相同,就說明是子父級關系
            if (id.equals(entity.getParentId())) {
                map.put("id", entity.getId());
                map.put("parentId", entity.getParentId());
                map.put("name", entity.getName());
                //查詢子級下的子級
                map.put("children", getChildren(data, entity.getId()));
                list.add(map);
            }
        }
        return list;
    }
           

    2、方式二:組裝帶有children關聯性的對象

        在實體列中定義一個 children集合:

private List<ResourceDO> children = new ArrayList<>();
           

       傳回的是實體類對象的所有值,這裡操作的都是集合存儲對象的引用

/**
     * 将有父子關系的資料轉換成樹形結構資料
     *
     * @return 最終的樹狀結構的集合資料
     */
    @Override
    public List<ResourceDO> getMuneTree2() {
        // 擷取資料庫中帶有有父子關系的資料
        List<ResourceDO> data = resourceDOMapper.selectAll();

        // 複制data資料
        List<ResourceDO> menuList = new ArrayList<>(data);
        // 周遊兩次data來組裝帶有children關聯性的對象,如果找到子級就删除menuList的資料
        for (ResourceDO entity : data) {
            for (ResourceDO entity2 : data) {
                //如果本級id與資料的父id相同,就說明是子父級關系
                if (entity.getId().equals(entity2.getParentId())) {
                    entity.getChildren().add(entity2);
                    menuList.remove(entity2);
                }
            }
        }
        return menuList;
    }
           

ends~

繼續閱讀