准备好了条件就可以查询了,借助olap4j的query包来组装MDX语句,API
建议同时阅读olap4j源码中的注释。
根据cube名称,创建cube对象
Cube cube = conn.getOlapSchema().getCubes().get(cubeName);
当然首先要建立一个连接,此处为conn.
cubeName,例如Foodmart中的”Sales”.
创建query对象
Query query = new Query(“query”, cube);
创建三个轴的对象
QueryAxis qa = query.getAxis(Axis.COLUMNS);
qa = query.getAxis(Axis.ROWS);
qa = query.getAxis(Axis.FILTER);
向轴上添加维度
qa.addDimension(query.getDimension(dimension));
括号内的dimension,如”Store”、”Measures”、”Time”
重复添加同一个维度会报错,故应先检测是否添加过。
例如有两个条件:Time.Year,Time.Month.
放入度量
query.getDimension(dimension).include(
Selection.Operator.MEMBER,
IdentifierNode.ofNames(dimension, level)
.getSegmentList());
括号内的level参数,指如”Unit Sales”、”Profit”
放入维度
放入维度比度量要复杂一些。
Level olapLevel = cube.getDimensions().get(dimension)
.getHierarchies().get(0).getLevels().get(level);
getHierarchies().get(0)指第一个(默认)的Hierarchy。
如果有多个Hierarchy,则应通过
getHierarchies().get(“Time.Weekly”)获取Level对象
最后的.get(level),level可以是”year”、”month”.
query.getDimension(dimension).include(olapLevel);
如果level中放入的是member,即形如Time.1997而不是Time.year,
query.getDimension(dimension).include(
Selection.Operator.INCLUDE_CHILDREN,
IdentifierNode.ofNames(levels).getSegmentList());
此处的参数levels是一个数组,依次存放member的各个层级,如”1997”、”Q1”、”3”
校验
query.validate();
如果想生成不完整的MDX则不要加上这行。
String mdx = query.getSelect().toString();
把MDX转成String类型。
最后附上代码
ps:我把条件封装在一个dto类中,每个对象保存一个条件,如Time.Year及其所在的轴、cube等信息。以下包含一些其他特性。
public class MDXGenerator {
//是否加上 Hierarchize()
private static boolean hierarchize_row=false;
private static boolean hierarchize_col = false;
public static String getMDX(MondrianOlap4jConnection conn, List<Recommend> list,Boolean swap,Boolean non_empty)
throws SQLException {
// list中的第一个,extra属性存放cube名称
String cubeName = list.get(0).getExtra();
// 根据名称获取cube
Cube cube = conn.getOlapSchema().getCubes().get(cubeName);
// 新建一个query
Query query = new Query("query", cube);
// 保存各轴上已经添加的dimension,重复添加维度会报错
String[] columnExist = new String[list.size()]; // column
String[] rowExist = new String[list.size()]; // row
String[] filterExist = new String[list.size()]; // filter
String fn="";
// 把条件放到三个轴上
for (