元数据 JSON

阅读(2190) 标签: 元数据json,

元数据JSON包含字段相关的一些信息,是最初始的输入。字段查询设置查询细节后,输出为查询JSON

参数说明

元数据JSON结构:

[

{

name : "group1",  //组名

fields : [       //字段数组

{  //字段属性

name : "field1",   //字段名

title : "中文字段名",   //字段别名

dataType : 3,   //数据类型

dateFormat : "yy -mm-dd",  //日期格式

timeFormat : "HH:mm:ss",   //时间格式

referData : [ 

{id:1, pId:0, name: ‘北京’,v:’1’ },

],

multi : 2   //是否允许多选,值为2表示不可多选

},…

]

},…

]

元数据JSON整体是一个数组。包含一个或多个元素(可看作分组)。一个元素是一组字段,对字段进行分组管理方便面上按组选字段。

每个字段对象中属性定义如下:

name:字段名,和表中的字段名一致;

title:字段别名,在面上显示,业务人员容易理解;

dataType:数据类型。1表示整数;2表示实数;3表示字符串;4表示日期。日期类型的数据在进行条件值编辑时,可使用日期控件;

dateFormat:日期格式,设置日期字段条件时使用;

timeFormat:时间格式,设置时间字段条件时使用;

referData:用选择方式编辑条件时的备选数据,可以是三状态切换按钮、多选按钮、下拉树等多种编辑风格;

referData的每一个备选项中的属性:

idpId:下拉树才需要这两个属性,表示节点的上下级关系,其它编辑风格时可以省略;

name:显示值;

v:真实值。

multi:用选择方式编辑条件时,是否可以选多个值。multi的值为1时,按钮可多选,值为2或者不设置时表示单选。

 

name为必须设置的参数,其他参数可选。

JSON 结构介绍

不同结构的元数据JSON,在字段列表和查询页面所呈现的形式各不相同。如字段分组和多选按钮的JSON呈现的形式如下图所示:

使用不同结构的元数据json不仅可以对字段进行分组,为字段设置别名,还可以定义多种编辑风格以帮助用户快速正确地录入查询条件值。

例如:三状态切换按钮、多选按钮、下拉列表、下拉树等。期待用什么方式在面上设置查询细节,就要生成相应的元数据JSON来驱动面。

 

l  字段分组

表中字段多时,通过组名name 设置分组,进行分类管理。

[

{

name : 'group1',//组名

fields : [  //字段数组

{name:'a'},

{name:'aa'}

]

},{

name : 'group2',//组名

fields : [  //字段数组

{name:'b'},

{name:'bb'}

]

},{

name : 'group3',//组名

fields : [  //字段数组

{name:'c'},

{name:'cc'}

]

}

]

使用分组功能,可将同一类数据划分到一组,方便查看。缺省显示全部字段。

下拉列表选择不同的分组时,字段列表仅列出该组包含的字段,如:选择group1

 

:只有一个分组时,不显示分组下拉列表框。

 

l  别名

使用别名可增加字段可读性,便于理解。字段名必须与表中的字段名称相同,别名可随意设置。

通过title 为字段定义别名,不使用title 时,默认显示name

[

{

name : 'group1',//组名

fields : [  //字段数组

{

name : 'StuId',  //字段名

title : '学生编号'  //字段别名

},{

name : 'Gender',  //字段名

title : '性别'  //字段别名

},{

name : 'Subject'

}

]

}

]

 

l  三状态切换按钮

三状态切换按钮是指有三种状态可以切换,且仅支持单选。

referData中备选项为2个时,字段会被设置成三状态切换按钮。

[

{

name : 'group1',//组名

fields : [  //字段数组

{

name : 'StuId',  //字段名

title : '学生编号'  //字段别名

},{

name : 'Gender',  //字段名

title : '性别',  //字段别名

referData : [  //三状态切换按钮。name为显示值,v为真实值。

{name:'',v:'M'},

{name:'',v:'F'}

]

},{

name : 'Subject',  //字段名

title : '科目'  //字段别名

}

]

}

]

本例中该按钮有3种显示方式:全部//女,在使用时只能选择一种状态:

 

l  多选按钮

referData中备选项不多于5个时,会列出全部备选项,且multi的值为1时,按钮可多选:

[

{

name : 'group1',//组名

fields : [  //字段数组

{

name : 'StuId',  //字段名

title : '学生编号' //字段别名

},{

name : 'Gender',  //字段名

title : '性别',  //字段别名

referData : [  //三状态按钮。name为显示值,v为真实值。

{name:'',v:'M'},

{name:'',v:'F'}

]

},{

name : 'Subject',  //字段名

title : '科目', //字段别名

referData : [  //多选按钮。name为显示值,v为真实值。

{name:'体育',v:' PE '},

{name:'数学',v:' Math '},

{name:'英语',v:' English '}

],

multi : 1

}

]

}

]

Subject字段referData的备选项有3个,则该按钮会出现3个子选项:体育/数学/英语。子选项可多选。

 

l  下拉列表

referData中备选项多于5个时,备选项会以下拉列表的形式呈现:

[

{

name : 'group1',//组名

fields : [  //字段数组

{

name : 'StuId',  //字段名

title : '学生编号' //字段别名

},{

name : 'Gender',  //字段名

title : '性别',  //字段别名

referData : [  //三状态按钮。name为显示值,v为真实值。

{name:'',v:'M'},

{name:'',v:'F'}

]

},{

name : 'Subject',  //字段名

title : '科目', //字段别名

referData : [  //多选按钮。name为显示值,v为真实值。

{name:'体育',v:' PE '},

{name:'数学',v:' Math '},

{name:'英语',v:' English '},

{name:'物理',v:' Physics'},

{name:'历史',v:'History '},

{name:'语文',v:'Chinese '}

],

multi : 1

}

]

}

]

multi的值为1时,下拉列表可多选。

multi的值为2,或者无multi时,下拉列表只能单选。

 

l  下拉树

referData备选项增加id/pId时表示父子关系,pId0时为顶级:

[

{

name : 'group1',//组名

fields : [  //字段数组

{

name : 'StuId',  //字段名

title : '学生编号' //字段别名

},{

name : 'Gender',  //字段名

title : '性别',  //字段别名

referData : [  //三状态按钮。name为显示值,v为真实值。

{name:'',v:'M'},

{name:'',v:'F'}

]

},{

name : 'Subject',  //字段名

title : '科目', //字段别名

referData : [  //多选按钮。name为显示值,v为真实值。

{name:'体育',v:' PE '},

{name:'数学',v:' Math '},

{name:'英语',v:' English '},

{name:'物理',v:' Physics'},

{name:'历史',v:'History '},

{name:'语文',v:'Chinese '}

],

multi : 1

},{

name : 'native',  //字段名

title : '户籍城市', //字段别名

referData : [  //多选按钮。name为显示值,v为真实值。idpId设置节点的上下级关系。

{id:1, pId:0, name:'北京',v:'1'},

{id:2, pId:0, name:'天津',v:'2'},

{id:3, pId:0, name:'上海',v:'3'},

{id:6, pId:0, name:'重庆',v:'4'},

{id:4, pId:0, name:'河北省',v:'5'},

{id:41, pId:4, name:'石家庄',v:'6'},

{id:42, pId:4, name:'保定',v:'7'},

{id:43, pId:4, name:'邯郸',v:'8'},

{id:44, pId:4, name:'承德',v:'9'},

{id:5, pId:0, name:'广东省',v:'10'},

{id:51, pId:5, name:'广州',v:'11'},

{id:52, pId:5, name:'深圳',v:'12'},

{id:53, pId:5, name:'东莞',v:'13'},

{id:54, pId:5, name:'佛山',v:'14'},

{id:6, pId:0, name:'福建省',v:'15'},

{id:61, pId:6, name:'福州',v:'16'},

{id:62, pId:6, name:'厦门',v:'17'},

{id:63, pId:6, name:'泉州',v:'18'},

{id:64, pId:6, name:'三明',v:'19'}

],

multi : 1

}

]

}

]

multi的值为1时,下拉树可多选。

multi的值为2,或者无multi时,下拉树只能单选。

 

多种 JSON 类型的使用

关于元数据JSON的使用方式有如下四种:

方法一:直接提供json字符串。

编辑【安装目录】\report\web\webapps\demo\raqsoft\guide\jsp\下的cq.jsp,使用json字符串生成元数据JSON

String metadata = "[{name:'group1',fields:[{name:'EID',title:'员工编号'},{name:'GENDER',title:'性别'},{name:'SALARY',title:'工资'}]}]";

 

结果如图:

 

方法二:提供一个服务器上的.json文件,元数据JSON来自.json文件。

.json文件内容如图:

该文件位于【安装目录】\report\web\webapps\demo\下。在commonQuery标签中指定metadata的值为 "myMetadata.json"

结果如图:

 

 

方法三:使用根据页面参数和当前登录用户动态生成的json字符串。

通用查询控件集成到应用系统后,通常由应用系统负责提供当前登录用户的信息以及要查询的表名。

比如将用户信息和表名从session中传递过来。本例为了演示,直接在jsp写了固定的值,手动改这个值来模拟不同登录用户。假如系统中有两个用户user1user2user1用户可以查看学生表或成绩表中的一部分字段;user2用户可以查询学生表或成绩表中的另一部分字段。那么我们就可以通过使用变量传递不同的值达到动态生成json字符串的目的。

cq.jsp中添加如下java代码判断:

<%

String tableName = "学生表";

String userId = "user2";

if ("成绩表".equals(tableName)){

if ("user1".equals(userId))

metadata = "[{name:'group1',fields:[{name:'CLASS',title:'班级'},{name:'STUDENTID',title:'学号'},{name:'SUBJECT',title:'科目'},{name:'SCORE',title:'成绩'}]}]";

else if ("user2".equals(userId))

metadata = "[{name:'group1',fields:[{name:'CLASS',title:'班级'},{name:'STUDENTID',title:'学号'}]}]";

} else if ("学生表".equals(tableName)){

if ("user1".equals(userId))

metadata = "[{name:'group1',fields:[{name:'STUDENTID',title:'学号'},{name:'Gender',title:'性别'},{name:'name',title:'姓名'}]}]";

else if ("user2".equals(userId))

metadata = "[{name:'group1',fields:[{name:'STUDENTID',title:'学号'},{name:'name',title:'姓名'}]}]";

}

%>

 

<raqsoft:commonQuery

metadata="<%=metadata%>"

params="<%=params%>"

cqx="<%=cqx%>"

/>

 

结果如图:

 

方法四:使用集算器脚本spl文件生成的json字符串。

使用集算器脚本spl文件(文件后缀为.splx/.spl/.dfx)从数据库中把表取出来,然后动态地生成元数据JSON

本小节内容要求用户对集算器脚本有一定的学习了解。

 

spl文件是通过润乾集算器生成的文件。在spl文件中可以执行各类数据分析与结构化计算,也可以自由访问数据库。通用查询在使用spl时,需在.splx文件的网格程序中使用return语句返回json串类型的结果集。

.splx文件内容如下:

 

A

 

1

=connect("demo")

连接demo数据源

2

=A1.query("select * from 员工 limit 1")

查询"员工"表中的一行数据

3

=create(name,dataType)

创建空序表

4

=A2.fname().run(c=~,val=A2(1).field(c),type=if(ifnumber(val):1,ifstring(val):3;4),A3.insert(0,c,type))

获取员工表中的字段名和字段数据类型,并将处理后的数据插入到A3

5

=create(name,fields)

创建空序表

6

>A5.insert(0,"员工表",A3)

将数据插入到 A5

7

>A1.close()

关闭数据源连接

8

return json(A5)

返回json

 

spl文件位于【安装目录】\report\web\webapps\demo\WEB-INF\reportFiles\commonQuery\下。spl类型的元数据使用相对路径,相对于应用根目录。在commonQuery标签中指定metadata的值为 "WEB-INF/reportFiles/commonQuery/QueryMetadata.splx"

 

结果如图:

 

这样就完成了使用数据库表生成元数据JSON的操作

 

但是如果想要换一个表查询时,本例中spl脚本就不通用了。因此我们还需要做一个通用模版,这样无论查询哪张表均不用再修改spl脚本,甚至还可以根据页面参数和当前登录用户用spl脚本动态的生成json字符串。具体可参考动态生成JSON小节。

动态生成 JSON

通过前面小节的介绍我们了解了元数据JSON的细节内容以及它如何驱动通用查询页面。现在我们再讲述下如何自动化的产生元数据JSON,最原始的素材是数据库里的表,我们需要一个程序能动态的把数据库里的表转换成元数据JSON,这中间还要考虑权限控制。

如果想让数据库里的表自动化的产生元数据JSON,那么我们需要一个程序能动态的把数据库里的表转换成元数据JSON,而使用spl(文件后缀为.splx/.spl/.dfx)是一个非常好的选择,使用集算器脚本可灵活生成所需元数据JSON

 

前面的spl例子中指定了"员工"表生成元数据JSON,现在对QueryMetadata.splx稍作修改,不指定表名而是通过参数传递表名,将spl另存为commonQueryMetadata.splx,修改文件内容如下:

 

A

 

1

=connect("demo")

连接demo数据源

2

>params=json(params)

json格式串解析成序表返回

3

=A1.query("select * from "+params.table+" limit 1")

根据表名参数table查询一行数据

4

=create(name,dataType)

创建空序表

5

=A3.fname().run(c=~,val=A3(1).field(c),type=if(ifnumber(val):1,ifstring(val):3;4),A4.insert(0,c,type))

获取table表中的字段名和字段数据类型,并将处理后的数据插入到A4

6

=create(name,fields)

创建空序表

7

>A6.insert(0,params.table+"",A4)

将数据插入到 A6

8

>A1.close()

关闭数据源连接

9

return json(A6)

返回json

 

参数定义:

 

表名作为参数,由外部传入。传入不同的表名可得到不同的元数据json,从而达到动态的目的。传入spl里的参数值格式随意,只要spl里按照如下格式正确解析就可以:

String params = "{'table': '员工', 'userId': '23'}";

 

commonQueryMetadata.splx脚本只涉及字段名和数据类型,形成最简单的元数据JSON,接下来在这个的基础上,我们一点点补充成完整功能的元数据JSON增加元数据JSON中的表现信息(分组管理、中文名、条件值的可选项等)。

 

l  设置字段别名,可用来给英文字段设置中文字段名。

7

'[{v:"EMPID",d:"员工编号"},{v:"EMPNAME",d:"姓名"},{v:"GENDER",d:"性别"},{v:"DEPT",d:"部门"},{v:"NATIVE",d:"户籍城市"},{v:"DEGREE",d:"学历"},{v:"BIRTHDAY",d:"生日"},{v:"SALARY",d:"工资"}]

>fieldNames=json(A7)

 

8

>A4=A4.derive(fieldNames.select(v==name).d:title)

 

 

 

l  增加性别三状态切换按钮、学历多选按钮、省市下拉树的数据。

10

'[{v:1,d:""},{v:2,d:""}]

>gender=json(A10)

 

11

'[{v:1,d:"小学"},{v:2,d:"初中"},{v:3,d:"高中"},{v:4,d:"大专"},{v:5,d:"本科"}]

>education=json(A11)

 

12

'[{id:1, pId:0, name:'北京',v:'1'},{id:2, pId:0, name:'天津',v:'2'},{id:3, pId:0, name:'上海',v:'3'},{id:6, pId:0, name:'重庆',v:'4'},{id:4, pId:0, name:'河北省',v:'5'},{id:41, pId:4, name:'石家庄',v:'6'},{id:42, pId:4, name:'保定',v:'7'},{id:43, pId:4, name:'邯郸',v:'8'},{id:44, pId:4, name:'承德',v:'9'},{id:5, pId:0, name:'广东省',v:'10'},{id:51, pId:5, name:'广州',v:'11'},{id:52, pId:5, name:'深圳',v:'12'},{id:53, pId:5, name:'东莞',v:'13'},{id:54, pId:5, name:'佛山',v:'14'},{id:6, pId:0, name:'福建省',v:'15'},{id:61, pId:6, name:'福州',v:'16'},{id:62, pId:6, name:'厦门',v:'17'},{id:63, pId:6, name:'泉州',v:'18'},{id:64, pId:6, name:'三明',v:'19'}]

>city=json(A12)

 

13

>A4=A4.derive(if(name=="GENDER":gender,name=="DEGREE":education,name=="NATIVE":city;null):referData)

 

 

14

>A4=A4.derive(1:multi)

 

 

 

l  拼元数据JSON时,按照字段类型分组,方便选字段。可根据需求改为其它要求的分组方式。

17

>A4.group(dataType).run(c=~,t=~(1).dataType,A16.insert(0,if(t==1:"数值字段",t==3:"字符字段";"日期字段"),c))

 

l  权限控制,示例代码如下

16

if (params.userId==23)

>data=A4.select("EMPID,EMPNAME,DEPT".split(",").pos(name)!=null)

17

else if (params.userId==24)

>data=A4.select("DEPT,BIRTHDAY,GENDER".split(",").pos(name)!=null)

18

=create(name,fields)

 

19

>data.group(dataType).run(c=~,t=~(1).dataType,A18.insert(0,if(t==1:"数值字段",t==3:"字符字段";"日期字段"),c))

 

 

参数中传入了用户ID,期望不同的用户看到不同的字段:

用户ID23时,选用EMPIDEMPNAMEDEPT字段生成的元数据JSON

用户ID24时,选用DEPTBIRTHDAYGENDER字段生成的元数据JSON

详细集算器脚本参考commonQueryMetadata.splx。该文件位于【安装目录】\report\web\webapps\demo\WEB-INF\reportFiles\commonQuery\下。

使用"员工"表生成元数据JSON结果如图:

参数说明

table:需要查询数据的表名。

metadataspl类型(文件后缀为.splx/.spl/.dfx)的元数据,仅支持相对路径,相对于应用根目录

table_name +spl类型的metadata用来生成最终的元数据json串。

rpx:报表模版,用来展示数据。可使用相对路径或绝对路径,使用相对路径时,相对于应用中配置文件raqsoftConfig.xml 里配置的Report中的home属性的路径。