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