请珍惜小编劳动成果,该文章为小编原创,转载请注明出处。

背景:

            在ligerui中(其他uI可能也大同小异),实现树形表格可以通过父子节点,也可以通过前缀编码生成树去实现,而使用前缀编码生成树时,树形表格需要的json数据是如下类型的:
     
var TreeDeptData = { Rows : [
{ id: '01', name: "企划部", remark: "1989-01-12",
children: [
{ id: '0101', name: "企划分部一", remark: "企划分部一"
},
{ id: '0102', name: "企划分部二", remark: "企划分部二", children:
[
{ id: '010201', name: "企划分部二 A组", remark: "企划分部二 A组" },
{ id: '010202', name: "企划分部二 B组", remark: "企划分部二 B组" }
]
},
{ id: '0103', name: "企划分部三", remark: "企划分部三" }
]
},
{ id: '02', name: "研发部", remark: "研发部" },
{ id: '03', name: "产品部", remark: "产品部" }
]
};

所以说,我们需要把普通的数据表格需要的json数据转化成这种样式。接下来我将向大家说一下我是怎么实现该功能的。


数据表的要求:

     要实现前缀编码生成树,需要在数据表中添加一些字段,必要的字段有:分级码,级别,前缀码,孩子节点个数,兄弟节点个数,下面是一个简单的建表语句,在创建数据表时里边的数据必须包含:
        
create table gradeDemo(
id int IDENTITY, -- id
gradeNum varchar(1), --级别
prev varchar(60), --前缀码
gradeCode varchar(60), --分级码
brotherNum varchar(5), --兄弟节点个数
childrenNum varchar(5) --孩子节点个数
);

其中分级码是从1-9,兄弟节点个数不包括自己,下面是数据表截图:




级别为1的分级码的前缀码为0,级别为2的分级码的前缀码为他父节点的分级码,后边的类推。

辅助类:

ObjectByJson类,里边有一个方法getListMapByJSONArrayFromJson(),参数为一个json数组,返回值为一个list<map>
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import net.sf.json.JSONArray; public class ObjectByJson { //参数格式:[{id:'id1',code:'code1',name:'name1'},{id:'id2',code:'code2',name:'name2'}]
public List<Map<String, Object>> getListMapByJSONArrayFromJson(String json) {
List list = new ArrayList();
JSONArray array = JSONArray.fromObject(json);
Map o = null;
for (int i = 0; i < array.size(); i++) {
o = (Map) array.get(i);
list.add(o);
}
return list;
}
}

核心代码:

package OpenSrc.Platform.CommonFun.Json;

import java.util.ArrayList;
import java.util.List;
import java.util.Map; /**
* 功能 : 将json转换成树形表格需要的json数据
* 内容简介:
**
* 创建日期:2014/05/24
* 创建人 :debug_run
* 版权所有:FFA团队
*/
public class TreeDataByJson {
ObjectByJson objectByJson=new ObjectByJson();;
String girdJson="";
public TreeDataByJson(){
}
/** 功能 : 将json转换成树形表格需要的json数据
* 内容简介:
**
* 创建日期:2014/05/24
* 创建人 :<span style="font-family: Arial, Helvetica, sans-serif;">debug_run</span> * @param jsonString
* @return
*/
public String getTreeJsonByJson(String jsonString){
try {
getTreeJsonByJson(jsonString,9);
} catch (StopMsgException e) {
//System.out.println(e);
}
return girdJson;
}
/** 功能 : 将json转换成树形表格需要的json数据
* 内容简介:
**
* 创建日期:2014/05/24
* 创建人 :<span style="font-family: Arial, Helvetica, sans-serif;">debug_run</span><span style="font-family: Arial, Helvetica, sans-serif;"> </span>
* @param jsonStr
* @return
*/
public void getTreeJsonByJson(String jsonString,int gradeNum){
String json="";
List<Map<String, Object>> newList1= new ArrayList<Map<String, Object>>(); //用于存放重新排好的数据(高层次)
List<Map<String, Object>> newList2= new ArrayList<Map<String, Object>>(); //用于存放重新排好的数据
String jsonStr=jsonString.substring(8, jsonString.length()-1); //获取jsonArray的那部分,去掉前边的rows:{
List<Map<String, Object>> list =objectByJson.getListMapByJSONArrayFromJson(jsonStr); //得到一个listMap
List removeList=new ArrayList(); //用来保存需要删除的数据的下标
for(int i=0;i<list.size();i++){
Map<String, Object> map=list.get(i); //当前的map
if(Integer.parseInt(map.get("gradeNum").toString())==gradeNum){ //低层
newList1.add(map);
removeList.add(i);
}
if(Integer.parseInt(map.get("gradeNum").toString())==(gradeNum-1)&&!map.get("childrenNum").equals("0")){ //高层且有孩子
newList2.add(map);
removeList.add(i);
} }//for if(newList2.size()==0||newList1.size()==0){
if(gradeNum==2){
girdJson=jsonString;
throw new StopMsgException(); //强制退出
}
getTreeJsonByJson(jsonString,(gradeNum-1));
}
for(int i=0;i<removeList.size();i++){ //从list中删除应该被删除的数据
int j=(Integer) removeList.get(i);
j=j-i; //每删除一个,其他的数据的下表前移
list.remove(j);
}
System.out.println(list.size());
for(int j=0;j<newList2.size();j++){ //遍历所有高层的数据
String gradeCode=newList2.get(j).get("gradeCode").toString(); //高层的分级码
String children="children:[";
for(int k=0;k<newList1.size();k++){ //遍历所有低层的数据
String prev=newList1.get(k).get("prev").toString();
if(prev.equals(gradeCode)){ //低层次的前缀码等于于高层次的分级码
children+=newList1.get(k)+",";
}
}
if(!children.equals("children:[")){
children=children.substring(0,children.length()-1);
}
children+="]}";
String oldData=newList2.get(j).toString(); //旧的数据
String newData="["+oldData.substring(0,oldData.length()-1)+","+children+"]"; //加上孩子后的数据,写成json数组的格式
Map<String, Object> newMap=objectByJson.getListMapByJSONArrayFromJson(newData).get(0); //把合并的数据转成map
newList2.set(j,newMap); //重新加入到高层次的list里
// }
}//for
for(int i=0;i<newList2.size();i++){ //将合并后的两个list---newList2转成json{},{},{}
json+=newList2.get(i)+",";
}
json=json.substring(0,json.length()-1); //去掉最后的逗号
String newJson="";
for(int i=0;i<list.size();i++){ //将list剩余的值再转成json,
newJson+=list.get(i)+",";
}
newJson="{\"Rows\":["+newJson+json+"]}"; //获取新的json串
if(gradeNum>2){ //若girdJson改变,就要退出递归
getTreeJsonByJson(newJson,(gradeNum-1));
}
if(girdJson==""){
girdJson=newJson;
System.out.println(girdJson);
throw new StopMsgException(); //强制退出递归
}
}
static class StopMsgException extends RuntimeException {
} }

上面的代码为核心代码,使用时调用getTreeJsonByJson(String jsonString)方法,参数是一个普通数据表格所需要的json数据,通过调用后将返回一个属树形表格所需要的json数据。


测试:

由于这个涉及到的东西太多,这里就简单测试一下,测试数据是一个json字符串,想必大家都知道怎么获取该json,这里就是不多说了,数据如下:
 
{
"Rows": [
{
"id": 1,
"brotherNum": "1",
"childrenNum": "1",
"gradeNum": "1",
"gradeCode": "001",
"prev": "0"
},
{
"id": 3,
"brotherNum": "0",
"childrenNum": "2",
"gradeNum": "2",
"gradeCode": "00101",
"prev": "001"
},
{
"id": 4,
"brotherNum": "1",
"childrenNum": "0",
"gradeNum": "3",
"gradeCode": "0010101",
"prev": "00101"
},
{
"id": 5,
"brotherNum": "1",
"childrenNum": "0",
"gradeNum": "3",
"gradeCode": "0010102",
"prev": "00101"
},
{
"id": 2,
"brotherNum": "1",
"childrenNum": "0",
"gradeNum": "1",
"gradeCode": "002",
"prev": "0"
}
]
}


JSONObject jobj,设jobj的值为上述数据,通过调用getTreeJsonByJson()方法:String json=jsonOP.getTreeJsonByJson(jobj.toString());得到的json数据格式如下:


{
"Rows": [
{
"id": 2,
"brotherNum": "1",
"childrenNum": "0",
"gradeNum": "1",
"gradeCode": "002",
"prev": "0"
},
{
"id": 1,
"brotherNum": "1",
"childrenNum": "1",
"gradeNum": "1",
"gradeCode": "001",
"prev": "0",
"children": [
{
"id": 3,
"brotherNum": "0",
"childrenNum": "2",
"gradeNum": "2",
"gradeCode": "00101",
"prev": "001",
"children": [
{
"id": 4,
"brotherNum": "1",
"childrenNum": "0",
"gradeNum": "3",
"gradeCode": "0010101",
"prev": "00101"
},
{
"id": 5,
"brotherNum": "1",
"childrenNum": "0",
"gradeNum": "3",
"gradeCode": "0010102",
"prev": "00101"
}
]
}
]
}
]
}

需要强调的是,调用该方法时,参数的格式必须和我测试数据的格式是一样的{“Rows”:[ { },{ },{ } ] }

总结:

这篇文章只是简单的说了一下怎么将从数据库里获取的数据转化成树形表格需要的格式,也就是查询部分,关于怎样给这棵树添加节点,自动生成这些分级码,前缀码等信息,也是个难点,以后有时间会写一篇文章专门说一下。








版权声明:本文为博主原创文章,未经博主允许不得转载。

玩转web之ligerui(二)---前缀编码生成树(分级码)实现树型表格的更多相关文章

  1. 玩转Web之easyui(二)-----easy ui 异步加载生成树节点(Tree),点击树生成tab(选项卡)

    关于easy ui 异步加载生成树及点击树生成选项卡,这里直接给出代码,重点部分代码中均有注释 前台: $('#tree').tree({ url: '../servlet/School_Tree?i ...

  2. 玩转Web之JavaScript(二)-----javaScript语法总结(二) 涉及Date与数组的语法

    Date: document.write(document.lastModified)  网页最后一次更新时间 a=new Date();  //创建 a 为一个新的时期象 y=a.getY ear( ...

  3. 玩转web之ligerui(一)---ligerGrid重新指定url

    请珍惜小编劳动成果,该文章为小编原创,转载请注明出处. 在特定情况下,我们需要重新指定ligerGrid的url来获取不同的数据,在这里我说一下我用的方法: 首先先定义一个全局变量,然后定义liger ...

  4. 玩转web之ligerui(一)---ligerGrid又一次指定url

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u012116457/article/details/27109227 请珍惜小编劳动成果.该文章为小 ...

  5. 第二十二章、 Model/View便利类树型部件QTreeWidget

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 树部件(Tree Widget)是Qt Designer中 Item Widgets(It ...

  6. Web Service 的创建简单编码、发布和部署

    最近,老大准备将已有的C/S架构项目中的通信部分做成通用,需要将其支持WebService为以后项目向着B/S架构升级做好铺垫,为此身为屌丝的我去各种百度WebService是个什么卵玩意,然后逐渐搭 ...

  7. Java Web高性能开发(二)

    今日要闻: 性价比是个骗局: 对某个产品学上三五天个把月,然后就要花最少的钱买最多最好的东西占最大的便宜. 感谢万能的互联网,他顺利得手,顺便享受了智商上的无上满足以及居高临下的优越感--你们一千块买 ...

  8. 分分钟带你玩转 Web Services【2】CXF

    在实践中一直在使用 JAX-WS 构建 WebService 服务,服务还是非常稳定.高效的. 但还是比较好奇其他的 WebService 开源框架,比如:CXF/Axis2/Spring WS等. ...

  9. JavaSE 手写 Web 服务器(二)

    原文地址:JavaSE 手写 Web 服务器(二) 博客地址:http://www.extlight.com 一.背景 在上一篇文章 <JavaSE 手写 Web 服务器(一)> 中介绍了 ...

随机推荐

  1. Socket层实现系列 — bind()的实现(二)

    本文主要内容:bind()的TCP层实现.端口的冲突处理,以及不同内核版本的实现差异. 内核版本:3.6 Author:zhangskd @ csdn blog TCP层实现 SOCK_STREAM套 ...

  2. 【52】java多线程剖析

    线程的状态: 线程共有下面4种状态: 新建状态(New): 新创建了一个线程对象,当你用new创建一个线程时,该线程尚未运行. 就绪状态(Runnable): 线程对象创建后,其他线程调用了该对象的s ...

  3. C语言之linux内核--BCD码转二进制与二进制转BCD码(笔试经典)

    在分析代码之前,我们先来了解一下,BCD码和二进制到底区别在哪? 学习过计算机原理的和数字电子技术这两门课的都会知道这两个到底是什么含义,也有的同学学过了,考过了,过了一段时间又忘记了,今天,我们通过 ...

  4. spring+mybaits多数据源使用

    一.在利用spring管理mybatis时可以同时配置多个数据源,并且数据源可以随时切换,但在多线程中多数据源的事务需要一定的配置. 多数据源配置: <bean id="postgre ...

  5. Oracle与Mysql时间格式化

    一,Oracle格式化时间: Oracle 获取当前日期及日期格式 获取系统日期:  SYSDATE()    格式化日期:     TO_CHAR(SYSDATE(),'YY/MM/DD HH24: ...

  6. git对远程分支和tag的操作

    技术 Git查看.删除.重命名远程分支和tag 11/17/2012zrong7条评论69,235 次查看 本站文章除注明转载外,均为本站原创或者翻译. 本站文章欢迎各种形式的转载,但请18岁以上的转 ...

  7. Mac OS 的属性列表文件plist装换

    Mac OS系统自身包含有转换plist的工具:plutil.其中-p是以human可读方式显示plist文件,而convert就是转换参数,其中支持的格式有:xml,二进制和json.下面拿一个实际 ...

  8. Runtime - ③ - 分类Category探究

    写博客只是为了让自己学的更深刻,参考:https://tech.meituan.com/DiveIntoCategory.html 分类(Category)是个啥玩意儿这里就不多介绍了,这里主要是研究 ...

  9. redis删除所有key

    flushdb 删除当前数据库的所有keyflushall  删除所有数据库的所有keydbsize   返回当前数据库的key的数量

  10. 重定向和servlet生命周期

    重定向(1)什么是重定向服务器通知浏览器向一个新的地址发送请求.注:可以发送一个302状态码和一个Location消息头.(该消息头包含了一个地址,称之为重定向地址),浏览器收到之后,会立即向重定向地 ...