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);
            }
        }
    }

 

posted @ 2018-10-28 18:38  天天大傻猫  Views(1461)  Comments(0Edit  收藏  举报