zoukankan      html  css  js  c++  java
  • FastJson:Json树的CRUD操作方法实现

    准备工作:json字符串

    [{
        "id": 1,
        "code": "FLOW_NODE_1",
        "name": "环节A",
        "children": [{
            "id": 2,
            "code": "RULE_NODE_1",
            "name": "规则A"
        }, {
            "id": 3,
            "code": "RULE_NODE_2",
            "name": "规则B"
        }, {
            "id": 4,
            "code": "PARALLEL_NODE_2",
            "name": "并行节点",
            "children": [{
                "id": 5,
                "code": "RULE_NODE_3",
                "name": "规则C1"
            }, {
                "id": 6,
                "code": "RULE_COLLECTION_1",
                "name": "规则集1",
                "children": [{
                    "id": 7,
                    "code": "RULE_NODE_4",
                    "name": "规则C21"
                }, {
                    "id": 8,
                    "code": "RULE_NODE_5",
                    "name": "规则C22"
                }]
            }]
        }, {
            "id": 9,
            "code": "MUTUAL_NODE_1",
            "name": "互斥节点",
            "children": [{
                "id": 10,
                "code": "RULE_NODE_6",
                "name": "规则D1"
            }, {
                "id": 11,
                "code": "RULE_NODE_7",
                "name": "规则D2"
            }]
        }]
    }, {
        "id": 12,
        "code": "FLOW_NODE_2",
        "name": "环节B"
    
    }]

    这里使用的springboot下FastJson下的API使用例子:

    步骤一:加入依赖

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>${fastjson.version}</version>
     </dependency>

    步骤二:

    parse方法的使用:例如把JSON文本parse为JSONObject或者JSONArray 

    更多参考:https://www.cnblogs.com/sunp823/p/5601399.html

    1.根据json树treeId查找json并返回给前端:

    controller:

    /**
         * @param treeId
         * @return
         */
        @ApiOperation(value="查询树信息", notes="查询树信息")
        @RequestMapping(value = "/api/v1/orders/findTree" ,method = RequestMethod.POST)
        public Map findTree(@ApiParam(required = true, value = "树id") @RequestParam Integer treeId
        ){
            return ActionHelper.responseOk(categoryTreeService.getJsonTree(treeId));
        }

    service:

     //根据id获取json树
        public JSONArray getJsonTree(Integer treeId){
            JSONArray jsonTree = JSONArray.parseArray(categoryTreeRepository.selectJsonTree(treeId));
            return jsonTree;
        }

    2.查找指定treeId的json树下对应的key-value的节点信息

    controller:

    /**
         * @param treeId 树id
         * @param key key名称
         * @param value value值
         * @return
         */
        @ApiOperation(value="查询节点信息", notes="查询节点信息")
        @RequestMapping(value = "/api/v1/orders/findNode" ,method = RequestMethod.POST)
        public Map findNode(@ApiParam(required = true, value = "树id") @RequestParam Integer treeId,
                            @ApiParam(required = true, value = "节点key") @RequestParam String key,
                            @ApiParam(required = true, value = "节点value") @RequestParam String value
        ){
            return ActionHelper.responseOk(categoryTreeService.getNode(treeId,key,value));
        }

    service:

    //根据节点key-value键值对,获取树下该节点信息
        public JSONObject getNode(Integer treeId,String key,String value){
            JSONArray jsonTree = JSONArray.parseArray(categoryTreeRepository.selectJsonTree(treeId));
            JSONObject node = getNode(jsonTree, key, value,new JSONObject());
            return node;
        }
    
     /**
         * 根据单一条件获取节点位置
         * @param body            查询目标的主体内容
         * @param key            筛选匹配条件条件对应--key
         * @param value            筛选匹配条件对应--value
         * @param result        缓存查询结果
         * @return
         */
        public static JSONObject getNode(JSONArray body,String key,Object value,JSONObject result) {
            for (int i = 0; i < body.size(); i++) {
                JSONObject jsonObject =body.getJSONObject(i);
                if (jsonObject.get(key).toString().equals(value.toString())) {
                    for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
                        result.put(entry.getKey(), entry.getValue());
                    }
                }else if(jsonObject.getJSONArray("children")!=null) {
                    getNode(jsonObject.getJSONArray("children"), key, value,result);
                }
            }
            return result;
        }

    3.删除指定treeId下的指定key-value的节点

    controller:

      @ApiOperation(value="删除节点信息", notes="删除节点信息")
        @RequestMapping(value = "/api/v1/orders/deldNode" ,method = RequestMethod.POST)
        public Map delNode(@ApiParam(required = true, value = "树id") @RequestParam Integer treeId,
                            @ApiParam(required = true, value = "节点key") @RequestParam String key,
                            @ApiParam(required = true, value = "节点value") @RequestParam String value
        ){
            return ActionHelper.responseOk(categoryTreeService.delNode(treeId,key,value));
        }

    service:

     //删除json树下指定的节点及其子节点
        public JSONObject delNode(Integer treeId,String key,String value){
            JSONArray jsonTree = JSONArray.parseArray(categoryTreeRepository.selectJsonTree(treeId));
            JSONObject node = getNode(jsonTree, key, value,new JSONObject());
            delNode(jsonTree, key, value);
            String a=jsonTree.toString();
            categoryTreeRepository.updateTree(a,treeId);
            return node;
        }
    
    
    /**
         * 根据单一条件删除节点
         * @param body        需要删除的目标主体
         * @param key        筛选匹配条件对应的key
         * @param value        筛选匹配条件对应的value
         */
        public  void delNode(JSONArray body,String key,Object value) {
            for (int i = 0; i < body.size(); i++) {
                JSONObject jsonObject =body.getJSONObject(i);
                if (jsonObject.get(key).toString().equals(value.toString())) {
                   Object obj= body.remove(i);
                    break;
                }else if(jsonObject.getJSONArray("children")!=null) {
                    delNode(jsonObject.getJSONArray("children"), key, value);
                }
            }
    
        }

    mapper:

    public interface CategoryTreeRepository extends JpaRepository<CategoryTree,String>, JpaSpecificationExecutor<CategoryTree> {
        //根据id获取json树字符串
        @Query(value="SELECT jsonTree from catagory_tree where id=?1",nativeQuery=true)
        String selectJsonTree(Integer id);
    
        @Modifying
        @Transactional
        @Query(value="UPDATE catagory_tree SET jsonTree = ?1  WHERE id = ?2",nativeQuery = true)
        void updateTree(String jsonTreeStr,Integer id);
    
    
    }

    4.在指定的key-value键值对节点下面添加节点,

      目的:children的value为JsonArray格式,在此属性下添加JsonObject节点

      依旧走步骤2判断节点是否存在,若存在则:

      1.判断此节点下是否存在key为children的属性:

      2.如果此节点存在key为children的属性,则在children下指定下标添加节点

      3.如果不存在key为children的属性,则添加children,新节点存进children

    controller:

      @ApiOperation(value="新建节点", notes="根据输入参数创建节点")
        @RequestMapping(value = "/tree_data/node/{treeId}", method = RequestMethod.POST)
        public Map addOne(@ApiParam(required = true, value = "分类树ID")@PathVariable Integer treeId,
                          @ApiParam(required = true, value = "节点key") @RequestParam String key,
                          @ApiParam(required = true, value = "节点value") @RequestParam String value,
                          @ApiParam(required = true, value = "插入下标") @RequestParam Integer index,
                          @ApiParam(required = true, value = "节点信息") @RequestBody Map map){
            return ActionHelper.responseOk(categoryTreeService.addNode(treeId,key,value,index,map));
        }

    service:

     //在json树下添加节点:
        public JSONArray addNode(Integer treeId,String key,Object value,Integer sequ,Map newNodeMap){
            JSONArray jsonTree = JSONArray.parseArray(categoryTreeRepository.selectJsonTree(treeId));
            Integer nodeId = (Integer)newNodeMap.get("id");
            JSONObject node = getNode(jsonTree, "id", nodeId,new JSONObject());
            System.out.println(node);
            if(!node.isEmpty()){
                throw new BadRequestException("此id的节点已存在");
            }
            //把map转化为JSONObject
            JSONObject newNode = new JSONObject(newNodeMap);
            addNode(jsonTree,key,value,sequ, newNode);
            return jsonTree;
        }
    
    
    /**
         * 增加节点
         * @param jsonArray     需要更新的目标主体
         * @param node          增加节点信息
         * @param sequ          数组的位置
         * @param key           目标主体中的字段名key
         * @param value         节点信息与key对应的value
         */
        public  void addNode(JSONArray jsonArray, String key, Object value, Integer sequ,JSONObject node) {
            for (Object obj : jsonArray) {
                JSONObject jsonObject = (JSONObject) obj;
                JSONArray children = jsonObject.getJSONArray("children");
                if (children != null) {
                    if (value.toString().equals(jsonObject.get(key).toString())) {
                        if(sequ > children.size()){
                            //如果下标大于此节点children的长度,则追加
                            children.add(children.size(), node);
                        }else{
                            //在指定位置增加
                            children.add(sequ-1, node);
                        }
                        return;
                    }
                    addNode(children,key,value,sequ,node);
                } else {
                    //直接判断是否要在此节点下增加个名为children键值对
                    if (value.toString().equals(jsonObject.get(key).toString())) {
                        JSONArray array = new JSONArray();
                        array.add(node);
                        jsonObject.put("children", array);
                        return;
                    }
                }
            }
        }

    5.根据节点id更改节点属性:

      涉及API:jsonObject.put(key,value)

      依旧先走步骤2查询节点是否存在,若存在则更改属性:

      如果更改的属性存在,则覆盖

      如果更改的属性不存在,则追加

    controller:

    @ApiOperation(value="更新节点信息", notes="更新节点信息")
        @RequestMapping(value = "/tree_data/node/{treeId}/{id}", method = RequestMethod.PATCH)
        public Map updateOne(@ApiParam(required = true, value = "分类树ID")@PathVariable Integer treeId,
                             @ApiParam(required = true, value = "节点ID")@PathVariable Integer id,
                             @ApiParam(required = true, value = "节点信息") @RequestBody Map map){
            return ActionHelper.responseOk(categoryTreeService.updateNode(treeId,id,map));
        }

    service:

    /**
         * 修改单个节点
         * @param treeId
         * @param nodeId
         * @param map
         * @return
         */
        @Transactional
        public JSON updateNode(Integer treeId, Integer nodeId, Map map) {
            JSONArray jsonTree = JSONArray.parseArray(categoryTreeRepository.selectJsonTree(treeId));
           //查询节点是否存在
            if(!getNode(jsonTree, "id", nodeId,new JSONObject()).isEmpty()){
                update(jsonTree,  "id",  nodeId,  map);
                //更新数据库
                String a=jsonTree.toString();
                categoryTreeRepository.updateTree(a,treeId);
            }else{
                throw new BadRequestException("此id的节点不存在");
            }
            return jsonTree;
    
        }
    
    
        /**
         * 根据条件更新节点
         * @param jsonArray 需要更新的目标主体
         * @param key       目标主体中的字段名key
         * @param value     更新节点信息与key对应的value
         * @param map      更新节点信息
         */
        public  void update(JSONArray jsonArray, String key, Object value, Map<String,Object> map) {
            for (int i = 0; i < jsonArray.size() ; i++) {
                JSONObject json=jsonArray.getJSONObject(i);
                if(value.toString().equals(json.get(key).toString())){
                    for (Map.Entry<String,Object> entry : map.entrySet()) {
                        json.put(entry.getKey(),entry.getValue());
                    }
                    break;
                }else if(json.getJSONArray("children")!=null) {
                    update(json.getJSONArray("children"), key, value,map);
                }
            }
        }
  • 相关阅读:
    android 开机启动
    android 获取lanucher 列表
    原创高端影楼人像专业磨皮法教程详解 附PSD源码
    [转]在SQLPLUS启动和停止Oracle数据库
    挑印刷时间最新的地图!
    Eclipse3.2下进行ArcGIS Server 9.2 Java WebADF开发手记 Eclipse使用技巧
    [藏]常用的匹配正则表达式和实例
    [藏]C# 中的常用正则表达式总结
    [转]使用uDig制作geoserver中需要的style
    [转]geoserver与OpenLayers配置入门
  • 原文地址:https://www.cnblogs.com/big-cut-cat/p/9864103.html
Copyright © 2011-2022 走看看