维度管理:核心操作当然是维度成员的增删改。维度管理分为维度管理与维度成员管理2部分:维度管理,\维度成员管理:
和普通增删改略有差别,维度管理CRUD的时候,除了增加维度字典相关数据,还应该维持olap相关维度、事实表。
后端开发还好,前端熟悉了一下ant Form表单,Modal调用的相关内容。
(共享维设置)
( 操作符)
在后端,共享维度的处理就是“维度名字+(共享)”形成的。
memberName += Constants.shareMemberMarking;
共享维度 只用插入字典表,不用插入olap维度表!
分为维度管理与维度成员管理2部分:维度管理,\维度成员管理:
一个维度成员 可以在多个分析模型当中,即一个维度成员可以在多个立方体(cube)当中,维度成员和立方体是1-*的关系;
维度区分是否多层级 isMultiLevelMember:是多层级成员
子维度范围 父维度范围:
自定义的维度成员,和一个或者多个特定的cube相关联,我们给cube定义了modtype,其实就是按位给cube一个编号,
001 是cube1;
010是cube2;
100是cube3
一个维度成员能在哪些cube当中用,看used_In,把每个cube的mod_type和used_in进行位运算!
如何理解isleafIncube?(待补充)
计算成员的定义:对应mdx的with member
计算成员必须校验,我们进行了2个校验:
校验的代码如下:
private static String testFormulaMdx(String formula, CDimension dimension,
DimMember member, CCube bgCube) {
String formulaMemberName = "[" + dimension.getName() + "].[VALIDATE_MEMBER]";
String str="WITH MEMBER " + formulaMemberName + " AS (" + formula
+ ") SELECT " + formulaMemberName + " ON COLUMNS FROM ["
+ bgCube.getName() + "]";
return str;
}
保存新增加维度成员到数据库:
增加一般维度,主要有如下操作:
- 增加字典表
- 增加维度表
要保存如下信息:
- 修改父节点信息
- 新增加的子节点信息
- 对应的计算公式
- 对应的别名表
- 成员聚合运算符信息
- 对应的olap引擎需要的维度表:
- 度别名表的处理:
一个维度 有多个对应的别名 放到单独的表当中ALIAS_TALBE ,
ALIAS_TALBE 就2个字段:Id、name
共享维度是给多个立方体共用的维度 不能和已有的维度重名
parent Member
cuurent Member
formular
formular表仅仅有2个字段:
- id: 也是维度成员id
- formularString
和维度成员对应的别名表:
一个维度成员,可以对应多个别名?aliases如:[["600","default"],["602","测试别名"]]
维度管理前端:
首先是选中维度类型
然后是选中相关维度成员节点:
{
"key": 600077,
"id": "600077",
"text": "rrr1000",
"checked": false,
"parentId": "600069",
"hasParent": true,
"hasChildren": false,
"btn": false,
"levelnum": 0
}
选择维度成员的时候,弹出模态框:
1、设置模态框可见性属性(DimForm state)
2、传递值给Modal(通过prop)
成员公式:
react中,获取iinput值的方法,和传统js略有差异,参见下文
后台服务必须有这样的方法:根据维度id,查询所有的维度成员!
构建公式-->构建维度成员
构建祖先成员的集合,构建children,这个是在构造缓存的时候,就完成了的。
String formatName=BusinessMethods.formatMember(memberName, generation);?再有后端向服务端吐数据之前,就搞这个
保存:
private synchronized void saveFormulaMember(final String formula, final DimMember pMember,
final DimMember ...) {
DBHelper.update(pMember);
DBHelper.save(cMember);
FormulaMember formulaMember = new FormulaMember();
formulaMember.setId(cMember.getMemberId());
formulaMember.setFormula(formula);
DBHelper.save(formulaMember);
}
删除维度成员:
最一般成员主要删除动作为,
- 删除事实表:如:delete from c1_fact1;
- 删除和事实表关联的维度表:delete from C1_DIM_YEAR where 1=1 and ID=?
- 删除数据字典表:
delete from COMMOBJECT o where o.id=601422
delete from C_YEAR where id=601422
一个是删除维度表中维度信息,一个是删除mondrian 维度表中的相关数据
能删除最顶级维度成员(通过检查代数)
删除维度成员本身及其关联的描述信息。(dimmember,description)
删除mondrian fact data与mondrian dim data;
删除成员操作信息
删除dim alias
删除事实表:其实就是根据cube name & dimession Id,构造删除事实表中数据的的sql
删除维度信息的时候,由于维度成员继承了comm object, 他们的结构是:
ps:在Spring Data JPA中删除相同的事务后插入
React Hooks 入门教程二:useState使用、useEffect参数作用
动态构建mdx:
/**
* 对外提供取得多维查询语句的接口
* @return 多维查询语句
*/
private String getMdxString(FormShadow formShadow,int[] pageLayout){
formShadow.getNoDetailMap().clear();
formShadow.getShareMemberMap().clear();
//CCube cube=formShadow.getCube();
//String cubeName=cube.getName();
//先简化问题 cube 名称给个固定值
String cubeName="Col_trade_detail";
List<List<List<DimMember>>> colMemberObjs = formShadow.getColMembers();
List<List<List<DimMember>>> rowMemberObjs = formShadow.getRowMembers();
List<List<DimMember>> pageMemberObjs = formShadow.getPageMembers();
List<List<DimMember>> viewMemberObjs = formShadow.getViewMembers();
String onCols = conMembers(colMemberObjs,formShadow);
String onRows = conMembers(rowMemberObjs,formShadow);
String onWheres = conWhereMembers(pageMemberObjs,viewMemberObjs,pageLayout,formShadow);
String mdxString = makeMdxString(cubeName,onCols,onRows,onWheres);
String withMemsStr = conWithMembers(colMemberObjs,rowMemberObjs,formShadow);
if(withMemsStr!=null){
mdxString = withMemsStr + mdxString;
mdxString=replaceTempFormulaMember(mdxString, formShadow);
}
return mdxString;
}
拼接子语句:
/**
* 根据行/列成员对象连接成员字符串
* @param formShadow
* @ param membersList 行成员/列成员对象的集合
* @return 连接成员字符串
*/
private static String conMembers(List<List<List<DimMember>>> membersList0, FormShadow formShadow) {
StringBuffer strBuffer=new StringBuffer();
if (membersList0 != null&&membersList0.size()>0) {
strBuffer.append("{");
for (int k = 0; k < membersList0.size(); k++) {
List<List<DimMember>> membersList = membersList0.get(k);
if (membersList != null&&membersList.size()>0) {
for (int i = 0; i < membersList.size(); i++) {
strBuffer.append("{");
List<DimMember> members=membersList.get(i);
for (int j = 0; j < members.size(); j++) {
DimMember member=members.get(j);
CDimension dim=member.getDimension();
String memberN=member.getNavigation();
/* if(member.getHasChildren()==1){
//非明细成员
formShadow.getNoDetailMap().put(member.getMemberId(), dim.getId());
}else{
memberN=buildShareMember(member, dim, formShadow,memberN);
}*/
strBuffer.append(memberN);
if (j != members.size() - 1) {
strBuffer.append(",");
}
}
strBuffer.append("}");
if (i != membersList.size() - 1) {
strBuffer.append("*");
}
}
}
if(k!=membersList0.size()-1){
strBuffer.append(",");
}
}
strBuffer.append("}");
}
return strBuffer.toString();
}
构建with模块的事情,暂时放一下
构建各个分语句的时候,需要考虑祖先的层级,毕竟mdx 中,对元素描述需要全路径。
delete Dimession member(int dim,int memberId):
动态生成的8条语句:(其中七条是删除)
Hibernate: delete from C1_FACT where 1=1 and ACCOUNT=?
Hibernate: delete from C1_DIM_ACCOUNT where 1=1 and ID=?
Hibernate: select commobject0_.id as id1_16_0_, commobject0_.description as description2_16_0_, commobject0_.formula as formula3_16_0_, commobject0_.generation as generation4_16_0_, commobject0_.has_children as has_children5_16_0_, commobject0_.last_modified as last_modified6_16_0_, commobject0_.name as name7_16_0_, commobject0_.obj_type as obj_type8_16_0_, commobject0_.parent as parent9_16_0_, commobject0_.position as position10_16_0_, commobject0_1_.datastoretype as datastoretype1_12_0_, commobject0_1_.datatype as datatype2_12_0_, commobject0_2_.datastoretype as datastoretype1_15_0_, commobject0_2_.datatype as datatype2_15_0_, commobject0_2_.key as key3_15_0_, commobject0_2_.used_in as used_in4_15_0_, commobject0_3_.datastoretype as datastoretype1_11_0_, commobject0_3_.datatype as datatype2_11_0_, commobject0_3_.used_in as used_in3_11_0_, commobject0_4_.datastoretype as datastoretype1_27_0_, commobject0_4_.datatype as datatype2_27_0_, commobject0_4_.dim_type as dim_type3_27_0_, commobject0_4_.used_in as used_in4_27_0_, commobject0_6_.type as type1_5_0_, commobject0_6_.used_in as used_in2_5_0_, commobject0_7_.datastoretype as datastoretype1_14_0_, commobject0_7_.datatype as datatype2_14_0_, commobject0_8_.datastoretype as datastoretype1_6_0_, commobject0_8_.datatype as datatype2_6_0_, commobject0_8_.type as type3_6_0_, commobject0_8_.used_in as used_in4_6_0_, commobject0_9_.type as type1_2_0_, commobject0_9_.datastoretype as datastoretype2_2_0_, commobject0_9_.datatype as datatype3_2_0_, commobject0_9_.used_in as used_in4_2_0_, commobject0_10_.approval as approval1_7_0_, commobject0_10_.cube_id as cube_id2_7_0_, commobject0_10_.form_folder as form_folder3_7_0_, commobject0_10_.description as description4_7_0_, commobject0_10_.scale as scale5_7_0_, commobject0_10_.showway as showway6_7_0_, commobject0_11_.datastoretype as datastoretype1_4_0_, commobject0_11_.datatype as datatype2_4_0_, commobject0_11_.sign as sign3_4_0_, commobject0_12_.alias as alias1_3_0_, commobject0_12_.mod_type as mod_type2_3_0_, commobject0_12_.type as type3_3_0_, case when commobject0_1_.id is not null then 1 when commobject0_2_.id is not null then 2 when commobject0_3_.id is not null then 3 when commobject0_4_.id is not null then 4 when commobject0_5_.id is not null then 5 when commobject0_6_.id is not null then 6 when commobject0_7_.id is not null then 7 when commobject0_8_.id is not null then 8 when commobject0_9_.id is not null then 9 when commobject0_10_.id is not null then 10 when commobject0_11_.id is not null then 11 when commobject0_12_.id is not null then 12 when commobject0_.id is not null then 0 end as clazz_0_ from commobject commobject0_ left outer join c_scenario commobject0_1_ on commobject0_.id=commobject0_1_.id left outer join c_year commobject0_2_ on commobject0_.id=commobject0_2_.id left outer join c_period commobject0_3_ on commobject0_.id=commobject0_3_.id left outer join icp_customdim commobject0_4_ on commobject0_.id=commobject0_4_.id left outer join c_form_folder commobject0_5_ on commobject0_.id=commobject0_5_.id left outer join c_dim commobject0_6_ on commobject0_.id=commobject0_6_.id left outer join c_version commobject0_7_ on commobject0_.id=commobject0_7_.id left outer join c_entity commobject0_8_ on commobject0_.id=commobject0_8_.id left outer join c_account commobject0_9_ on commobject0_.id=commobject0_9_.id left outer join c_form commobject0_10_ on commobject0_.id=commobject0_10_.id left outer join c_currency commobject0_11_ on commobject0_.id=commobject0_11_.id left outer join c_cube commobject0_12_ on commobject0_.id=commobject0_12_.id where commobject0_.id=?
Hibernate: delete from c_account where id=?
Hibernate: delete from commobject where id=?
Hibernate: DELETE FROM MEMBER_OPERATOR WHERE MEMBER_ID=?
Hibernate: DELETE FROM DIM_ALIAS WHERE MEMBER_ID=?
Hibernate: DELETE FROM ATTR_BASE_MEMBER WHERE BASE_MEMBER_ID=?
编辑的逻辑:
dimManagement要使用dim_info:
给dim_info传递dimession member Id,
在dim_info中获取维度成员信息
ps:Spring Boot(五):Spring Boot Jpa 的使用