将数据转换成树型层级的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字符串。