Java 后台生成 JSONArray 树

来源:互联网 发布:360云盘mac版怎么用 编辑:程序博客网 时间:2024/06/04 00:38

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

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

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

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

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

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

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

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

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

  /**
     * 递归树  java层数据
     * @param mapper
     * @param parentId
     * @return
     */
    public static List<TreeWyRoom> infiniteTree( WyRoomMapper mapper,Integer parentId,Integer xqId){
        List<TreeWyRoom> treeRooms = new ArrayList<>();
        WyRoomExample  example = new WyRoomExample();
        WyRoomExample.Criteria  ccc=example.createCriteria();
        ccc.andParentIdEqualTo(parentId);
        ccc.andXqIdEqualTo(xqId);
        List<WyRoom> wyRooms = mapper.selectByExample(example);
        Comparator<WyRoom> comparator = new Comparator<WyRoom>(){
            @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<TreeWyRoom> treeRoom,JSONObject o) {
        JSONArray array = new JSONArray();
        for (TreeWyRoom room : treeRoom) {
            JSONObject oo = new JSONObject();
            List<TreeWyRoom> 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<WyRoom> wyRooms = mapper.selectByExample(example);    //返回结果    JSONArray jsonArray=new JSONArray();    //region 构造树json    Map<Integer,TreeWyRoom> mapObj=new HashMap<>();    Map<Integer,Link<Integer>> mapRelation =new HashMap<>();    List<Integer> rootList=new LinkedList<>();    for(WyRoom wyRoom : wyRooms){//把所有的TreeWyRoom存入mapObj中        mapObj.put(wyRoom.getId(),new TreeWyRoom(wyRoom));        Link<Integer> 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<Integer,TreeWyRoom> mapObj,Map<Integer,Link<Integer>> 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这些  如果你喜欢 可以按照给出的思想 自己写写看

写过一遍后就会理解 



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





0 0