分析表单布局的概念:
第一小节,我们已经介绍过布局的概念,这里以图再说明如下:
(假如对维度不进行分组)
(上图中,分组的情况有7个布局 (不含页面、视点相关布局))
页面、视点可以看成另外隐藏在表单背后的维度的行、列(不是准确描述)。
其余参考我前面写的:非税olap分析平台的设计与实现(一)--数据仓库模型中,相关内容。
整体而言,查询分为三个层次,1)布局类型上的查询、2)特定布局类型、特定组上的查询 3)特定布局查询
获取特定表单 特别布局类型上的List<List<List<DimMember>>> getFormMbrsAsLayoutGroup(formId,layoutType...);
获取特定表单 特别布局类型 特定组 List<List<DimMember>> tempResult = getFormMbrsAsLayout(formId,layoutType,groupId......);
特定布局上的成员的查询:
这样分2种情况:
List<DimMember> layoutMbrs =getMemberWithQueryType(...) 这种情况不展开查询函数;
List<DimMember> layoutMbrs =getMembersByQueryType(...) 这种情况展开查询函数;
实现(由顶层到细节):
1、取得行/列上的集合:
List<List<List<DimMember>>> dimMembers_col = getFormMbrsAsLayoutGroup(form, MConstants.LAYOUT_COL, true);
2、取得一个布局类型的组上的集合,这里布局类型指的是行、列、页面、视点,关键参数为 form、维度类型、组号:
List<List<DimMember>> tempResult = getFormMbrsAsLayout(form,
layoutType, groupPosition, isOpenQueryType);
3、取得一个具体布局类型上 特定组的的布局,由具体布局,获得dimession,.另外一个方法是:考虑到所有组的维度dimesssion 是否也可以根据行列类型,获取所有组的dimession,关键参数为 form、维度类型、组号
List<CFormLayout> getAxisFormLayoutList(int formId,
int groupPosition, int layoutType)
4、上一步获取到的是 :一个特定表单、特定布局类型、特定组上布局信息,考虑到在一个表单 的特定布局上,所有组的类 布局信息是一样的,应该也有其他办法获取相关数据。现在遍历上一步获取到的布局信息,获取一个组内的所有维度成员信息。
List<List<DimMember>> mbrs = new ArrayList<List<DimMember>>();
......
List<DimMember> layoutMbrs = new ArrayList<DimMember>();
for (int i = 0; i < layouts.size(); i++) {
//取得一个特定布局(特定组、特定组内特定的布局)的成员集合List<DimMember>
layoutMbrs = getLayoutMbrs(form.getCubeId(), layouts.get(i),
isOpenQueryType);
mbrs.add(layoutMbrs);
}
5、获取一个布局上,具体维度成员集合:
layoutMbrs = getLayoutMbrs(form.getCubeId(), layouts.get(i),
isOpenQueryType);
这一步,逻辑略复杂。
首先是要获取特定布局上一个维度成员的集合,然后对这个结果进行相关处理::
List<CFormMbr> formMbrs = getFormLayoutMembersByLayoutId(layout.getId());
6、getFormLayoutMembersByLayoutId方法中,通过调用getFormLayoutMembersByLayoutId获取维度成员集合,getFormLayoutMembersByLayoutId方法的实现:
/**
* 通过布局ID获取布局成员列表
*
* @param layoutId
* @return
*/
@Override
public List<CFormMbr> getFormLayoutMembersByLayoutId(int layoutId) {
List<CFormMbr> cFormMbrs=new ArrayList<CFormMbr>();
//方法一 :从数据库当中获取数据
//CFormMbr fomMmeber = new CFormMbr();
// fomMmeber.setLayoutId(layoutId);
// Example<CFormMbr> example = Example.of(fomMmeber);
// List<CFormMbr> formMembers=formMbrMapper.findAll(example);
// return formMembers;
//方法二:从缓存当中获取这个数据
try {
//cFormMbrs=(List<CFormMbr>)cacheHelp.getObjectInCache(Constants.C_FORMMbr,new C_FormMbr_layoutId_PK(false),layoutId);
cFormMbrs=(List<CFormMbr>)cacheHelp.getObjectInCache(CFormMbr.class,new C_FormMbr_layoutId_PK(false),layoutId);
} catch (CacheException e) {
e.printStackTrace();
}
return cFormMbrs;
}
7.getFormLayoutMembersByLayoutId方法中,对特定布局的成员信息(CFormMbr),进行遍历处理:
for (int i = 0; i < formMbrs.size(); i++) {
boolean isCompare = false; //?
DimMember member = null;
memberId = formMbrs.get(i).getMemberId();
queryType = formMbrs.get(i).getQueryType();
if (isOpenQueryType) { //展开的情况
if (formMbrs.get(i).getType() == MConstants.FORM_MBR_TYPE_VAR) {
//todo
.....
} else {
tempMembers = memberEval.getMembersByQueryType(queryType, memberId, cubeId, layout.getDimId());
if (tempMembers != null && tempMembers.size() > 0) {
Iterator<DimMember> memberIterator = tempMembers.iterator();
while (memberIterator.hasNext()) {
DimMember beAddM = memberIterator.next();
boolean isHas = false;
for (DimMember temp : members) {
if (temp.getMemberId() == beAddM.getMemberId()) {
isHas = true;
break;
}
}
if (isHas) {
memberIterator.remove();
}
}
}
members.addAll(tempMembers);
}
} else { //closed node
.....
}
......
}
8.下面,我们只讨论节点是全展开,且是普通节点的情况,关键是下面的的方法,根据memberId 和 query Type,返回相应节点集合,如这个节点quey type是“子代包含”则把相应节点全部返回。
tempMembers = memberEval.getMembersByQueryType(queryType, memberId, cubeId, layout.getDimId());
9.memberEval.getMembersByQueryType方法中,首先要把CFormMbr转为DimMember对象:
DimMember curMember=getMemberInDimByMemberId(memberId, dimId);
具体实现(方法一:从数据库中查的方式):
/**
* 获取维度成员
* @param memberId
* 维度成员ID
* @param dimId
* 维度ID
* @return
*/
@Override
public DimMember getMemberInDimByMemberId(int memberId, int dimId) {
DimMember object=null;
CDimension dimension = getDimInstanceById(dimId);
int obj_type=dimension.getObjType();
switch (obj_type) {
case MConstants.DIM_ACCOUNT:
object =accountMapper.getOne(memberId);
break;
case MConstants.DIM_ENTITY:
object =entityMapper.getOne(memberId);
break;
case MConstants.DIM_YEAR:
object =yearMapper.getOne(memberId);
break;
case MConstants.DIM_PERIOD:
object =periodMapper.getOne(memberId);
break;
case MConstants.DIM_VERSION:
object =versionMapper.getOne(memberId);
break;
case MConstants.DIM_SCENARIO:
object=scenarioMapper.getOne(memberId);
break;
case MConstants.DIM_CURRENCY:
object =curencyMapper.getOne(memberId);
break;
}
return object;
}
从缓存中查的方式:略
构建formGrid,最后重要形成三个数组,一个描述行标表头部分,一个描述列表头部分,一个描述表格数据区部分。行标题背后是行维,列表头后面是列维,表格区背后是事实数据。