将数据表封装成自定义TreeNode,再将TreeNode生成字串

  • 格式:doc
  • 大小:99.50 KB
  • 文档页数:10

由zTree的示范我们看到zTree支持多种数据类型,我认为json是最好的,项目中json肯定来自数据库,不可能就这样纯粹静态的,如何将数据库表中的属性信息生成json呢,这是关键问题,比如数据表读出的数据可能如下:1<pre name="code" class="java">//用一个集合模拟数据表的内容,也就是一下集合的内容完全可以查询自数据库2List<SysFunction> treeList = new ArrayList<SysFunction>();3treeList.add(new SysFunction("L01", null, "营销管理"));4treeList.add(new SysFunction("L02",null,"客户管理"));5treeList.add(new SysFunction("L03",null,"服务管理"));6//营销管理的子功能7treeList.add(new SysFunction("L0101","L01","创建销售机会"));8treeList.add(new SysFunction("L0102","L01","指派销售机会"));9treeList.add(new SysFunction("L0103","L01","制定开发计划"));10treeList.add(new SysFunction("L0104","L01","执行开发计划"));11//指派销售机会的子功能12treeList.add(new SysFunction("L010201","L0102","经理指派"));13treeList.add(new SysFunction("L010202","L0102","主管指派"));14//客户管理的子功能15treeList.add(new SysFunction("L0201","L02","客户信息管理"));16treeList.add(new SysFunction("L0202","L02","客户流失管理"));17//服务管理子功能18treeList.add(new SysFunction("L0301","L03","咨询服务管理"));19treeList.add(new SysFunction("L0302","L03","投诉服务管理"));20treeList.add(new SysFunction("L0303","L03","查询服务管理"));这里的SysFunction类封装的是系统功能表,这个类的定义如下:21/**22* 系统功能对象23* */24class SysFunction {2526private String code;27private String parentCode;28private String title;2930/**功能编号*/31public String getCode() {32return code;33}3435public void setCode(String code) {36this.code = code;37}38/**父级功能编号*/39public String getParentCode() {40return parentCode;41}4243public void setParentCode(String parentCode) {44this.parentCode = parentCode;45}46/**功能名称,现在树上的节点文本*/47public String getTitle() {48return title;49}5051public void setTitle(String title) {52this.title = title;53}5455public SysFunction(String code, String parentCode, String title) {56super();57this.code = code;58this.parentCode = parentCode;59this.title = title;60}6162public SysFunction() {63super();64}65}每个功能可能有一个父功能,也可能没有,如下将他们封装成Json字串呢?定义TreeNode类代表树形节点,注意观察这个类,关键代码都在里面实现了,比如如何让节点携带信息、如何将节点解析成JSON字串、如何向一个节点及子孙节点添加属性信息:66/**自定义的树节点*/67class TreeNode {68// 节点携带的值69private Map<String, Object> tag;7071// 儿子节点72private List<TreeNode> nodes;7374/**节点信息键值对,该属性不会为空指针,但可能没有键值对存在[就是map.size()==0]*/75public Map<String, Object> getTag() {76if (tag == null)77tag = new HashMap<String, Object>();78return tag;79}8081public void setTag(Map<String, Object> tag) {82this.tag = tag;83}8485/**获得所有子节点,该属性不会为空指针,但可能没有集合元素存在*/86public List<TreeNode> getNodes() {87if (nodes == null)88nodes = new ArrayList<TreeNode>();89return nodes;90}9192public void setNodes(List<TreeNode> nodes) {9394this.nodes = nodes;95}9697public TreeNode(Map<String, Object> tag, List<TreeNode> nodes) {98super();99this.tag = tag;100this.nodes = nodes;101}102103public TreeNode() {104super();105}106107public TreeNode(Map<String, Object> tag) {108super();109this.tag = tag;110}111112/**113* <pre>114* 将当前TreeNode解析为JSON字串构造的目标格式示例:115* {116* id:1,117* name:'手机',118* nodes:[119* {id:11,name:'诺基亚'},120* {id:12,name:'三星',nodes:[121* {id:121,name:'I9000(联通版)'},122* {id:122,name:'I9000(移动版)'},123* {id:123,name:'Galaxy Naos'}124* ]},125* {id:13,name:'索爱'}126* ]127* }128* </pre>129* */130public String toJson(){131if (this.getNodes().size() == 0)132throw new RuntimeException("节点不能没有任何属性"); 133return parseTreeNode(this);134}135136@Override137public String toString() {138// TODO Auto-generated method stub139return toJson();140}141142/**143* <pre>144* 将当前TreeNode解析为JSON字串构造的目标格式示例: 145* {146* id:1,147* name:'手机',148* nodes:[149* {id:11,name:'诺基亚'},150* {id:12,name:'三星',nodes:[151* {id:121,name:'I9000(联通版)'},152* {id:122,name:'I9000(移动版)'},153* {id:123,name:'Galaxy Naos'}154* ]},155* {id:13,name:'索爱'}156* ]157* }158* </pre>159* */160private String parseTreeNode(TreeNode node) {161if (node == null)162throw new RuntimeException("节点不能为空");163StringBuilder nodeBuilder = new StringBuilder("{");// JSON对象开始164// 把Map中的键值对构造成json对象属性165for (Map.Entry<String, Object> kvp : node.getTag().entrySet()) {166if (kvp.getV alue().getClass() == String.class)167nodeBuilder.append(kvp.getKey() + ":'" + kvp.getV alue() + "',");168else169nodeBuilder.append(kvp.getKey() + ":" + kvp.getV alue() + ","); 170}171172// 构造子节点173nodeBuilder.append("nodes:["); // 子节点开始174for (TreeNode cnode : node.getNodes()) {175if (cnode == null)176continue;177nodeBuilder.append(parseTreeNode(cnode) + ",");// 递归调用ParseTreeNode返回一个完整的JSON字串:"{属性1:value,属性2:value}"178}179if (nodeBuilder.charAt(nodeBuilder.length() - 1) == ',')// 去掉末尾逗号180nodeBuilder.deleteCharAt(nodeBuilder.length() - 1);181nodeBuilder.append("]"); // 子节点结束182183nodeBuilder.append("}"); // JSON对象结束184185return nodeBuilder.toString();186}187188189190/**191* 向指定节点及其子孙节点添加一个属性192* @author jiang193* @param node 被放置属性的节点194* @param isrecursive 是否递归[当前节点的子孙节点]放置属性195* @param entries 放置的属性键值对196*/197private void _putProperty(TreeNode node,Boolean isrecursive,Map.Entry<String,Object>...entries) {198if (entries!=null)199for (Map.Entry<String, Object> entry : entries) {200node.getTag().put(entry.getKey(),entry.getV alue());201}202if (!isrecursive)203return;204for (TreeNode n : node.getNodes()) {205_putProperty(n,isrecursive,entries);206}207}208209/**210* 向指定节点及其子孙节点添加一个属性211* @author jiang212* @param node 被放置属性的节点213* @param isrecursive 是否递归[当前节点的子孙节点]放置属性214* @param entries 放置的属性键值对215*/216public void putProperty(Boolean isrecursive,Map.Entry<String,Object>...entries) { 217_putProperty(this,isrecursive,entries);218}219}下面这个类是使用这个TreeNode生成需要的json字串,这个类解决了一个最关键的问题:就是将List集合封装成了一棵树TreeNode220public class TreeService {221222public String getTree() {223224//用一个集合模拟数据表的内容,也就是一下集合的内容完全可以查询自数据库225List<SysFunction> treeList = new ArrayList<SysFunction>();226treeList.add(new SysFunction("L01", null, "营销管理"));227treeList.add(new SysFunction("L02",null,"客户管理"));228treeList.add(new SysFunction("L03",null,"服务管理"));229//营销管理的子功能230treeList.add(new SysFunction("L0101","L01","创建销售机会"));231treeList.add(new SysFunction("L0102","L01","指派销售机会"));232treeList.add(new SysFunction("L0103","L01","制定开发计划"));233treeList.add(new SysFunction("L0104","L01","执行开发计划"));234//指派销售机会的子功能235treeList.add(new SysFunction("L010201","L0102","经理指派"));236treeList.add(new SysFunction("L010202","L0102","主管指派"));237//客户管理的子功能238treeList.add(new SysFunction("L0201","L02","客户信息管理"));239treeList.add(new SysFunction("L0202","L02","客户流失管理"));240//服务管理子功能241treeList.add(new SysFunction("L0301","L03","咨询服务管理"));242treeList.add(new SysFunction("L0302","L03","投诉服务管理"));243treeList.add(new SysFunction("L0303","L03","查询服务管理"));244245246//将这个从集合封装成TreeNode247//构造一个根节点248TreeNode rootNode = new TreeNode();249rootNode.getTag().put("id", "L1");250rootNode.getTag().put("name", "CRM系统");251252//将这个集合封装成Map253Map<String,TreeNode> treeNodeMap = new HashMap<String,TreeNode>(); 254//下面的循环完成两个功能:255// 1.将所有对象封装成Map里面的键值对,且值是TreeNode类型256// 2.将没有父节点的TreeNode添加到根节点rootNode257for(SysFunction sysFunction:treeList){258TreeNode node = new TreeNode();259node.getTag().put("id",sysFunction.getCode());260node.getTag().put("name", sysFunction.getTitle());261treeNodeMap.put(sysFunction.getCode(),node);262if (sysFunction.getParentCode()==null || "".equals(sysFunction.getParentCode())){//如果没有父节点则添加到根节点263rootNode.getNodes().add(node);264}265}266267268//下面的代码建立节点之间的从属关系269for(int i=0;i<treeList.size();i++){270SysFunction sysFunction = treeList.get(i);271if (treeNodeMap.containsKey(sysFunction.getParentCode())){//如果当前功能的父级功能编号在treeNodeMap中存在272treeNodeMap273.get(sysFunction.getParentCode())//找出父节点274.getNodes() //父节点的子节点集合275.add( //向子节点集合添加子节点276treeNodeMap.get(sysFunction.getCode())//找出子节点277);278}279}280281//给根节点和它的子孙节点添加一个属性信息(open:true),展开节点282rootNode.putProperty(true, new SimpleEntry<String,Object>("open",true));283284return rootNode.toJson();285}286}下面是我的示范页面,如何使用这个类,注意观察id等于treeDemo3的代码:287<html>288<head>289<meta http-equiv="content-type" content="text/html; charset=UTF-8">290<link rel="stylesheet" href="demoStyle/demo.css" type="text/css"></link> 291<link rel="stylesheet" href="zTreeStyle/zTreeStyle.css" type="text/css">292<script type="text/javascript" src="jquery-1.4.2.js"></script>293<script type="text/javascript" src="jquery.ztree-2.6.js"></script>294<script type="text/javascript" src="asyncData/demoData.js"></script>295<script type="text/javascript">296var setting1 = {showline:true,checkable:true};297//json298var zTreeNodes1 = [299{ "name":"google", "url":"", "target":"_blank"},300{ "name":"baidu", "url":"", "target":"_blank"}, 301{ "name":"sina", "url":"", "target":"_blank"}302];303var zTreeNodes2 = [304{id:1,name:'手机',nodes:[305{id:11,name:'诺基亚',nodes:[306{id:111,name:'C6(音乐版)'},307{id:112,name:'X6(导航版)'},308{id:113,name:'5230(世博版)'}309]},310{id:12,name:'三星'},311{id:13,name:'索爱'},312{id:14,name:'多普达'}313]},314{id:2,name:'电脑'},315{id:3,name:'家电'}316];317window.onload=function(){318$("#treeDemo1").zTree(setting1,zTreeNodes1);319$("#treeDemo2").zTree({showline:true,checkable:false},zTreeNodes2);320$("#treeDemo3").zTree({showline:true,checkable:true},[<%=new TreeService().getTree() %>]);321};322</script>323</head>324<body>325<div class="zTreeDemoBackground" style="float:left;">326<ul id="treeDemo1" class="tree" style="float:left;"></ul>327</div>328<div class="zTreeDemoBackground" style="float:left;">329<ul id="treeDemo2" class="tree"></ul>330</div>331<div class="zTreeDemoBackground" style="float:left;">332<ul id="treeDemo3" class="tree"></ul>333</div>334335</body>336</html>运行结果:。