Java 后台生成 JSONArray 树

java后台通过访问数据库得到数据来生成树是很常用的的方法

这个有很多种方法可以实现 我这里就说对我比较印象深刻的两种方法

一种是自己写的  后台拼接一点点的数据就要9秒之多

另一种是我借鉴我老大写得  后台拼接只要3面左右  (两种方法是在同样的数据和同样的环境中比较的)

为什么说这两种方法会对我影响比较大呢

因为这两种方法代表了两种实现思想

首先是我这个比较low的  我的思想就是先获取到根节点 然后通过根节点的 id  来查询所有 parentId = 根id 的数据

这样通过递归来实现 非常的慢 而且代码量非常的多

我也不怕丢人 贴出来给大家看看  

  /**
     * 递归树  java层数据
     * @param mapper
     * @param parentId
     * @return
     */
    public static List infiniteTree( WyRoomMapper mapper,Integer parentId,Integer xqId){
        List treeRooms = new ArrayList<>();
        WyRoomExample  example = new WyRoomExample();
        WyRoomExample.Criteria  ccc=example.createCriteria();
        ccc.andParentIdEqualTo(parentId);
        ccc.andXqIdEqualTo(xqId);
        List wyRooms = mapper.selectByExample(example);
        Comparator comparator = new Comparator(){
            @Override
            public int compare(WyRoom o1, WyRoom o2) {
                return o1.getCode().compareTo(o2.getCode());
            }
        };


        Collections.sort(wyRooms,comparator);


        for( WyRoom wyRoom : wyRooms ){
            TreeWyRoom treeWyRoom = new TreeWyRoom();
            treeWyRoom.setId(wyRoom.getId());
            treeWyRoom.setParentId(wyRoom.getParentId());
            treeWyRoom.setLevel(wyRoom.getLevel());
            treeWyRoom.setPcId(wyRoom.getPcId());
            treeWyRoom.setXqId(wyRoom.getXqId());
            treeWyRoom.setCode(wyRoom.getCode());
            treeWyRoom.setAlias(wyRoom.getAlias());
            treeWyRoom.setType(wyRoom.getType());
            treeWyRoom.setCreateDate(wyRoom.getCreateDate());
            treeWyRoom.setCreator(wyRoom.getCreator());
            treeWyRoom.setLastModDate(wyRoom.getLastModDate());
            treeWyRoom.setLastModifier(wyRoom.getLastModifier());
            treeRooms.add(treeWyRoom);
        }
        for(TreeWyRoom treeRoom : treeRooms){
            if(treeRoom.getLevel()==2){
                treeRoom.setPlzj(true);
            }
            treeRoom.setChildren(infiniteTree(mapper,treeRoom.getId(),xqId));
        }
        return treeRooms;
    }


    /**
     * 把递归树拼接成JSON
     * @param treeRoom
     * @param o
     * @return
     */
    public static JSONArray jsonTree(List treeRoom,JSONObject o) {
        JSONArray array = new JSONArray();
        for (TreeWyRoom room : treeRoom) {
            JSONObject oo = new JSONObject();
            List child = room.getChildren();
            oo.put("id", room.getId());
            oo.put("parentId", room.getParentId());
            oo.put("level",room.getLevel());
            oo.put("pcId",room.getPcId());
            oo.put("xqId",room.getXqId());
            oo.put("code",room.getCode());
            oo.put("type",room.getType());
            oo.put("plzj",room.getPlzj());
            oo.put("alias",room.getAlias());
            oo.put("creator",room.getCreator());
            oo.put("createDate",room.getCreateDate());
            oo.put("lastModifier",room.getLastModifier());
            oo.put("lastModDate",room.getLastModDate());


            if (child != null && child.size() > 0) {
                oo.put("children",jsonTree(child,oo));
            }
            array.add(oo);
        }
        return array;
    }

我的方法是通过两个递归来实现的  第一个递归获取到所有的数据 生成一个对象树

然后通过第二个递归来形成一个json树 最后返回jsonarray

这个方发很浅显  一点都不好 现在让我看来烂透了  

除了让人可以更加明了的看到数据展示 其他一点用处都没有  

在执行过程中会造成大量的数据库访问 ,对内存和缓存造成大量的浪费  

这种方法的思想就是 典型的  我先获取一个点 通过这个点上的信息 来去找数据库对应的下级信息 在返回后封装children

这是个错误的示范  大家最好不要借鉴--------------------------------------------------------------------------------------------------------------------

现在让我们来看看高手 大牛  写得同样是后台Java生成的树  但是就是快 

他的思想就是我先把我所有的信息都获取到 封装到一个集合中 之后再用到的时候在我的集合中获取

下面是代码 我会有重点介绍


private JSONArray getJsonArray(Integer xqId,Integer parentId){
    //1.获取所有的room表  根据小区id
    WyRoomExample example = new WyRoomExample();
    WyRoomExample.Criteria criteria = example.createCriteria();
    example.setOrderByClause("id asc");//排序
    criteria.andXqIdEqualTo(xqId);
    if(parentId != null)
        criteria.andParentIdEqualTo(parentId);


    List wyRooms = mapper.selectByExample(example);


    //返回结果
    JSONArray jsonArray=new JSONArray();

    //region 构造树json
    Map,TreeWyRoom> mapObj=new HashMap<>();
    Map,Link> mapRelation =new HashMap<>();
    List rootList=new LinkedList<>();

    for(WyRoom wyRoom : wyRooms){//把所有的TreeWyRoom存入mapObj中
        mapObj.put(wyRoom.getId(),new TreeWyRoom(wyRoom));
        Link link = new Link<>();
        link.parent = wyRoom.getParentId();
        //存的是 当前room的id 并把 link存进去当作child
        mapRelation.put(wyRoom.getId(),link);

        if (wyRoom.getParentId() != 0) {  //如果不是顶级节点
            //如果当前room的parnetId 不是0 那么就用它的parentid 来在存放关系的mapRelation中查找 并存放在link的childrens中
            mapRelation.get(wyRoom.getParentId()).childrens.add(wyRoom.getId());
        }else {//是楼栋
            rootList.add(wyRoom.getId());
        }
    }
    for(Integer roomId : rootList){ //遍历所有楼栋得到下面的子节点
        JSONObject json = JSONObject.parseObject(getJsonString(roomId,mapObj,mapRelation));
        jsonArray.add(json);
    }

    return  jsonArray;
}

/**递归生成JSON树*/
private  String  getJsonString( int rootKey,Map,TreeWyRoom> mapObj,Map,Link> mapRelation){
    TreeWyRoom room = mapObj.get(rootKey);
    String s = String.format("{'id':'%d','parentId':'%d',level:'%d',pcId:'%d', xqId:'%d',code:'%s',type:'%s',plzj:'%b',alias:'%s'",
   room.getId(),room.getParentId(),room.getLevel(),room.getPcId(),room.getXqId(),room.getCode(),room.getType(),room.getPlzj(),room.getAlias());
    if (mapRelation.get(rootKey).childrens.size()==0){
        s=s +"}";
    }else{
        String splitDot="";
        StringBuilder sb=new StringBuilder();
        for(Integer childKey : mapRelation.get(rootKey).childrens ){
                sb.append( splitDot).append(getJsonString(childKey, mapObj, mapRelation));
                splitDot=",";
        }
        s=s + ",children:["+sb.toString()+"]}";
    }
    return s;
}
class Link<T> {//链结点
    List<T> childrens=new ArrayList<T>(); // 孩子id;
    T parent; //父母id
}

这个方法的思想就是获取所有的相关信息循环 封装成 map 方便获取

然后在通过自定义类Link 封装上下级关系 然后在存在一个公用的map中

这样 按照id的顺序就可以先把所有的父节点找出来

然后在父节点存起来 不是父节点的就在上下级关系的map中找自己的关系 

最后通过递归来实现 JSONArray

============================================================

PS:我贴出来的代码是我们项目的 会有很多的不全 像是pojo这些  如果你喜欢 可以按照给出的思想 自己写写看

写过一遍后就会理解 



最后感谢 网络上前辈 大牛 提供的案例和帖子 博客 谢谢 感谢老大的悉心教导  





你可能感兴趣的:(Java)