将数据转换成树型层级的Json格式的String

有时候我们项目里面需要将树型关系的数据转换成Json格式的String字符串

假设数据库中的数据如下

需要转换后输出的字符串的结果如下(对应的层级的关系)

[

  {name:'爷爷',id:'1',content:'老人辈',parentId:'0',expanded: true,children:[

    {name:'爸爸',id:'2',content:'长辈',parentId:'1',expanded: true,children:[

          {name:'儿子',id:'4',content:'晚辈',parentId:'2',leaf:true},{name:'女儿',id:'5',content:'晚辈',parentId:'2',leaf:true}

       ]},{name:'叔叔',id:'3',content:'长辈',parentId:'1',leaf:true}
] } ]

相应的代码资料网上可以找到

1、树节点类

 1 import java.util.ArrayList;
 2 import java.util.HashMap;
 3 import java.util.List;
 4 import java.util.Map;
 5 
 6 /**
 7  * 树节点类(用于模拟树型结构关系中的节点)
 8  */
 9 public class TreeNode {
10     public static final String TREENODE_ATTRIBUTE_NAME_NAME = "name";       // 字段属性name
11     public static final String TREENODE_ATTRIBUTE_NAME_ID = "id";           // 字段属性id
12     private Map<String,Object> attributes = new HashMap<String, Object>();  // 字段属性的Map
13 
14     private TreeNode parent = null;                                         //当前节点的父节点
15     private List<TreeNode> child = new ArrayList<TreeNode>();               //当前节点的子节点
16     private boolean isCheck = false;                                        //当前节点是否被勾选标志
17 
18 
19     /*
20         无参构造函数
21      */
22     public  TreeNode(){
23         super();
24     }
25 
26     /**
27      * 获取/设置 节点的属性name
28      * @return
29      */
30     public String getName() {
31         return (String) attributes.get(TREENODE_ATTRIBUTE_NAME_NAME);
32     }
33     public void setName(String name) {
34         attributes.put(TREENODE_ATTRIBUTE_NAME_NAME,name);
35     }
36 
37     /**
38      * 获取/设置 节点的属性id
39      * @return
40      */
41     public String getId() {
42         return (String) attributes.get(TREENODE_ATTRIBUTE_NAME_ID);
43     }
44     public void setId(String id) {
45         attributes.put(TREENODE_ATTRIBUTE_NAME_ID,id);
46     }
47 
48     /**
49      * 获取/设置 节点需要在树形结构中显示的信息
50      * @return
51      */
52     public Map<String, Object> getAttributes() {
53         return attributes;
54     }
55     public void setAttributes(Map<String, Object> attributes) {
56         this.attributes = attributes;
57     }
58 
59     /**
60      * 获取/设置 节点是否被勾选信息
61      * @return
62      */
63     public boolean isCheck() {
64         return isCheck;
65     }
66     public void setCheck(boolean check) {
67         isCheck = check;
68     }
69 
70     /**
71      * 获取/设置 节点父节点信息
72      * @return
73      */
74     public TreeNode getParent() {
75         return parent;
76     }
77     public void setParent(TreeNode parent) {
78         this.parent = parent;
79     }
80 
81     /**
82      * 是否存在/获取/设置/添加 节点子节点信息
83      * @return
84      */
85     public boolean hasChildren(){
86         return child.size()>0;
87     }
88     public List<TreeNode> getChild() {
89         return child;
90     }
91     public void setChild(List<TreeNode> child) {
92         this.child = child;
93     }
94     public void addChild(TreeNode treeNode){
95         treeNode.setParent(this);
96         child.add(treeNode);
97     }
98 }

2、树型节点的属性Map类

 1 import java.util.HashMap;
 2 import java.util.Map;
 3 
 4 /**
 5  * 树型节点的属性Map(用于操作节点的各个属性,如name,id)
 6  */
 7 public class TreeAttributesMap {
 8     private Map<String,Object> attributes = new HashMap<>();     //存放属性的Map
 9 
10     /**
11      * 有参构造函数
12      * @param id
13      * @param name
14      */
15     public TreeAttributesMap(Object id,Object name){
16         attributes.put(TreeNode.TREENODE_ATTRIBUTE_NAME_ID,id);
17         attributes.put(TreeNode.TREENODE_ATTRIBUTE_NAME_NAME,name);
18     }
19 
20     /**
21      * 获取属性的Map
22      * @return
23      */
24     public Map<String, Object> getAttributes() {
25         return attributes;
26     }
27 
28     /**
29      * 往属性的Map中添加属性
30      * @param name
31      * @param value
32      */
33     public void putAttributes(String name,Object value){
34         attributes.put(name,value);
35     }
36 }

3、定义一些树型结构相关的接口(方便以后拓展)

 1 /**
 2  * 定义一般普通的树节点的接口
 3  */
 4 public interface ISimpleTreeNode {
 5 
 6     /**
 7      * 每个树节点都具备自身的一些属性
 8      * @return
 9      */
10     public TreeAttributesMap getTreeAttributesMap();
11 }
1 /**
2  * 定义层级树节点的接口
3  */
4 public interface ILevelTreeNode  extends ISimpleTreeNode{
5 
6     public int getParentId();
7     public int getId();
8 }
1 public interface ITreeParser<T> {
2     /**
3      * 解析数据
4      * @param data
5      * @return
6      */
7      List<T> parser(Object data);
8 }

4、树类

 1 /**
 2  * 树类 (根据自身需求对数据进行解析和转换)
 3  */
 4 public class Tree {
 5     private ITreeParser<TreeNode> treeParser;
 6     private int treeType;                        //转换标志(可以拓展)
 7     private Object data;                         //数据源
 8 
 9     /**
10      * 有参构造函数
11      * @param data
12      * @param treeType
13      */
14     public Tree(Object data,int treeType){
15         this.data = data;
16         this.treeType = treeType;
17     }
18 
19     /**
20      * 数据转换 data ---> json格式
21      * @return  json格式的String
22      */
23     public String toJsonTree(){
24         String json  = "";
25         if (treeType == 1){
26             treeParser = new LevelTreeParser();
27             json = toLevelTree();
28         }else if (treeType == 2){
29             //XXX树型结构
30         }else if (treeType == 3){
31             //XXX树型结构
32         }else{
33             //other树型结构
34         }
35         return json;
36     }
37 
38     private String toLevelTree(){
39         String jsonString = "";
40         List<TreeNode> nodes = treeParser.parser(data);
41         StringBuffer sb = new StringBuffer();
42         sb.append("[");
43         parserLevelNodeToJson(sb,nodes);
44         sb.append("]");
45         jsonString = sb.toString();
46         return  jsonString;
47     }
48 
49     private void parserLevelNodeToJson(StringBuffer sb,List<TreeNode> nodes){
50         Iterator<TreeNode> it = nodes.iterator();
51         while(it.hasNext()){
52             TreeNode node = it.next();
53             boolean isLeaf = node.hasChildren();
54             sb.append("{");
55             Map<String,Object> attributes = node.getAttributes();
56             for(String key:attributes.keySet()){
57                 Object obj = attributes.get(key);
58                 if (obj != null)
59                     sb.append(key + ":'" + obj.toString() + "',");
60             }
61             if (isLeaf){
62                 sb.append("expanded: true,children: [");
63                 parserLevelNodeToJson(sb,node.getChild());
64                 if (it.hasNext()){
65                     sb.append("]},");
66                 }else{
67                     sb.append("]}");
68                 }
69             }else{
70                 if (it.hasNext()){
71                     sb.append("leaf:true},");
72                 }else{
73                     sb.append("leaf:true}");
74                 }
75             }
76         }
77     }
78 }

5、层级树状结构解析实现类

 1 import java.util.HashMap;
 2 import java.util.List;
 3 import java.util.Map;
 4 
 5 public class LevelTreeParser implements ITreeParser<TreeNode>{
 6 
 7     private Map<Object,TreeNode> treeNodeMap = new HashMap<Object, TreeNode>();
 8     TreeNode root = new TreeNode();
 9 
10     public List<TreeNode> parser(Object data){
11         //将数据data强转为List<ILevelTreeNode>格式
12         List<ILevelTreeNode> list = (List<ILevelTreeNode>) data;
13         //List<TreeNode> nodes = new ArrayList<TreeNode>();
14 
15         //list不为空且大小不为0
16         if (list != null && list.size()>0){
17 
18             //加强for循环list
19             for (ILevelTreeNode levelTreeNode:list){
20                 TreeNode item = new TreeNode();
21                 //获取每个树节点的属性
22                 item.setAttributes(levelTreeNode.getTreeAttributesMap().getAttributes());
23                 //封装每个树节点
24                 treeNodeMap.put(levelTreeNode.getId(),item);
25             }
26             //再次遍历所有的树节点
27             for (ILevelTreeNode levelTreeNode:list){
28                 TreeNode parent = treeNodeMap.get(levelTreeNode.getParentId());
29                 TreeNode treeNode = treeNodeMap.get(levelTreeNode.getId());
30                 if (parent == null){
31                     root.addChild(treeNode);
32                 }else{
33                     parent.addChild(treeNode);
34                 }
35             }
36         }
37         return root.getChild();
38     }
39 }

6、解析格式选择类

1 /**
2  * 解析格式选择类 (用于接受数据源并选择解析格式)
3  */
4 public class BaseParser {
5     public static String parserListToLevelTree(List list){
6         Tree tree = new Tree(list,1);
7         return  tree.toJsonTree();
8     }
9 }

 7、数据库的Model类treeLevel

要实现接口ILevelTreeNode并实现getTreeAttributesMap的方法,把数据库字段对应的类中的属性都封装起来

 1 public class treeLevel implements ILevelTreeNode {
 2 
 3     private int id;
 4     private int parentId;
 5     private String name;
 6     private String content;
 7 
 8     @Override
 9     public int getId() {
10         return id;
11     }
12 
13     public void setId(int id) {
14         this.id = id;
15     }
16 
17     @Override
18     public int getParentId() {
19         return parentId;
20     }
21 
22     public void setParentId(int parentId) {
23         this.parentId = parentId;
24     }
25 
26     public String getName() {
27         return name;
28     }
29 
30     public void setName(String name) {
31         this.name = name;
32     }
33 
34     public String getContent() {
35         return content;
36     }
37 
38     public void setContent(String content) {
39         this.content = content;
40     }
41 
42     @Override
43     public TreeAttributesMap getTreeAttributesMap() {
44         TreeAttributesMap treeMap = new TreeAttributesMap(this.id,this.name);
45         treeMap.putAttributes("content",this.content);
46         treeMap.putAttributes("parentId",this.parentId);
47         return treeMap;
48     }
49 }

8、Dao层(查询数据库表中所有的记录)

 1 @Mapper
 2 public interface MyDao { 3     @Select("SELECT * FROM treelevel")
 4     List<treeLevel> getTreeLevelList();
 5 }

9、Server层就省略了,最后只要在Controller层提供Server层调用Dao层访问数据库,将返回的结果List传入静态方法BaseParser.parserListToLevelTree()中即可。

最后,总结一下

a.先为自己的树型节点定义好接口,比如每个节点有获取自己的id、父节点id、属性集合等方法。

b.根据数据库字段创建好对应的类的Model,这里Model类需要实现之前定义好节点的接口,便于后面代码的接入。

c.创建好Parser转换类,将传入List形式的数据转换成自己想要的节点链表形式的数据(对每个节点封装好父节点、子节点们和自身属性集合等)。

d.创建好Tree数据选择解析类,将转换好的节点数据集合解析成自己想要的Json格式的String字符串。

 

posted on 2018-08-22 10:38  呼噜噜噜噜  阅读(6502)  评论(3编辑  收藏  举报

导航