有時候咱們項目裏面須要將樹型關係的數據轉換成Json格式的String字符串java
假設數據庫中的數據以下node
須要轉換後輸出的字符串的結果以下(對應的層級的關係)數據庫
[ {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}
] } ]
相應的代碼資料網上能夠找到json
一、樹節點類app
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 }
二、樹型節點的屬性Map類ide
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 }
三、定義一些樹型結構相關的接口(方便之後拓展)函數
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 }
四、樹類this
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 }
五、層級樹狀結構解析實現類spa
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 }
六、解析格式選擇類code
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 }
七、數據庫的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 }
八、Dao層(查詢數據庫表中全部的記錄)
1 @Mapper 2 public interface MyDao { 3 @Select("SELECT * FROM treelevel") 4 List<treeLevel> getTreeLevelList(); 5 }
九、Server層就省略了,最後只要在Controller層提供Server層調用Dao層訪問數據庫,將返回的結果List傳入靜態方法BaseParser.parserListToLevelTree()中便可。
最後,總結一下
a.先爲本身的樹型節點定義好接口,好比每一個節點有獲取本身的id、父節點id、屬性集合等方法。
b.根據數據庫字段建立好對應的類的Model,這裏Model類須要實現以前定義好節點的接口,便於後面代碼的接入。
c.建立好Parser轉換類,將傳入List形式的數據轉換成本身想要的節點鏈表形式的數據(對每一個節點封裝好父節點、子節點們和自身屬性集合等)。
d.建立好Tree數據選擇解析類,將轉換好的節點數據集合解析成本身想要的Json格式的String字符串。