將數據轉換成樹型層級的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字符串。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM