Mondrian API

Mondrian API

Created 星期一 24 十月 2016

http://mondrian.pentaho.com/api/index.html
Mondrian 是一个独立的引擎,一般都是通过嵌入到应用的方式来使用它,只需要在类路径加个类库就可以。实际上有多套BI 解决方案都是通过集成Mondrian 的方式来实现多维分析。
本章介绍编程方式连接Mondrian,执行MDX 查询的方法。使用mondrian 需要有一个数据库的连接和多维数据的描述文件(Schema 文件)。

Mondrian 本身执行mdx 查询的接口位于mondrian.olap 包。
下面例子中,"Catalog=steelwheels.hsql.xml"指定了模式文件的位置。
DriverManager 类跟Connection 接口都位于mondrian.olap 包,跟java.sql 无关。

 

CatalogLocator cl = new CatalogLocatorImpl();

Connection connection = DriverManager.getConnection("Provider=mondrian;Jdbc=jdbc:hsqldb:hsql://localhost/xdb;Catalog=steelwheels.hsql.xml;", cl);

String qs = "SELECT"+ " [Product].[Line].Members ON ROWS,"+ " [Time].[Years].Members ON COLUMNS"+ " FROM [SteelWheelsSales]";

Query query = connection.parseQuery(qs);

Result result = connection.execute(query);

Connection 的execute 方法已成了标记为淘汰的方法。现在mondrian 推荐通过olap4j 的方式来使用了。遍历结果集的方法可参考类mondrian.web.servlet.MdxQueryServlet。

SERVLET
mondrian.web.servlet.MdxQueryServlet 是一个Servlet,提供了在Java Web 应用中使用Mondrian 的简单方式。它从接收请求参数的MDX 查询语句,执行查询,遍历结果集并生成HTML 表格,然后输出到客户端。
例如接收如下的MDX 语句:
with
member [Measures].[Store Sales Last Period] as '([Measures].[Store Sales],
Time.PrevMember)'
select
{[Measures].[Store Sales Last Period]} on columns,
TopCount([Product].[Product Department].members,5, [Measures].[Store Sales LastPeriod])} on rows from Sales
where ([Time].[199
8])

OLAP4J

olap4j 是mdx 的Java 接口标准,类似于JDBC 是sql 的接口标准。olap4j 已成为Java 访问mdx 的事实标准。Mondrian推荐使用olap4j 接口来访问。
在API 上olap4j 跟JDBC 也很相似,事实上olap4j 的主要接口就是继承JDBC接口。
以下给出MDX 查询的简单示例。olap4j 的更多内容如获取元数据、轴变换、上卷/下钻以及MDX 解析/验证等,请参考olap4j 的API 或规范文档。olap4j 也支持XMLA
,请参考XMLA 一节。
import java.sql.Connection;
import java.sql.DriverManager;
import org.olap4j.Axis;
import org.olap4j.Cell;
import org.olap4j.CellSet;
import org.olap4j.CellSet
import org.olap4j.CellSetMetaData;
import org.olap4j.OlapConnection;
import org.olap4j.OlapStatement;
import org.olap4j.OlapWrapper;
import org.olap4j.Position;
import org.olap4j.layout.CellSetFormatter;
import org.olap4j.layout.RectangularCellSetFormatter;
import org.olap4j.metadata.Cube;
import org.olap4j.metadata.Member;
建立连接
跟JDBC 执行sql 查询类似,同样是通过Class.forName 的方式加载驱动类,然后从
DriverManager 创建连接。实际上DriverManager 和Connection 类就是java.sql 包里的。
OlapConnection 是java.sql. Connection 的子接口。
"Catalog=/path/to/steelwheels.hsql.xml"指定了模式文件的位置。

 

Class.forName("mondrian.olap4j.MondrianOlap4jDriver");

Connection connection = DriverManager.getConnection("jdbc:mondrian:Jdbc=jdbc:hsqldb:hsql://localhost/xdb;Catalog=/path/to/steelwheels.mondrian.xml;");

OlapWrapper wrapper = (OlapWrapper)connection;

OlapConnection olapConnection =wrapper.unwrap(OlapConnection.class);

连接mysql 数据库,可以这样:
jdbc:mysql://localhost/steelwheels;JdbcUser=root;JdbcPassword=pass;
在JDBC4.0(JDK1.6)以后,由于增加了java.sql.Wrapper 接口,提供了统一的方式了获取封装类(当然需要JDBC 驱动来实现),因此不需要OlapWrapper 接口。上面后两行可以变成一行:
OlapConnection olapConnection =connection.unwrap(OlapConnection.class);

执行查询
OlapStatement 也是java.sql.Statement 的子接口(当然java.sql.Connection 的
createStatement 方法必须返回java.sql.Statement 类型)。

 

OlapStatement statement = olapConnection.createStatement();

CellSet cellSet = statement.executeOlapQuery(

" select [Time].[Years].Members ON COLUMNS,"+ " [Product].[Line].Members ON ROWS "+ " from [SteelWheelsSales]");

这样就得到了查询结果集CellSet,相当于JDBC 的ResultSet,实际上CellSet 就是ResulSet的子接口。

遍历结果集
以下是读取结果集的方法,跟JDBC 有很大不同,毕竟MDX 结果集是多维的。

 

List<CellSetAxis> axes = cellSet.getAxes();

List<Position> cps =axes.get(Axis.COLUMNS.axisOrdinal()).getPositions();

List<Position> rps =axes.get(Axis.ROWS.axisOrdinal()).getPositions();

for (Position rposition : rps) {

    for (Member m : rposition.getMembers()) {

        System.out.print("["+m.getName()+"]\t");

    }

    System.out.print("| ");

    for (Position cposition : cps) {

        for (Member m : cposition.getMembers()) {

            System.out.print("["+m.getName()+"] ");

        }

        Cell cell = cellSet.getCell(cposition, rposition);

        String value = cell.getFormattedValue();

        System.out.print(value+"| ");

    }

    System.out.println();

}

上面代码的两重循环是已知道只有两个轴的写法,如果预先不知道有几个轴,就不能这么写。
Axis.COLUMNS.axisOrdinal()得到轴的序号0,Axis.ROWS.axisOrdinal()得到
1。直接写0,1 也可以。
Position 表示轴上的维度,一个轴可能有多个维度,因此每个轴得到一个Position 的
列表。
Member 表示维度的一个成员,用来生成表头
Cell 表示一个数据单元格,需要传入每个轴的Position 列表来获取一个Cell(多个
维度的交叉点)。
如果只需要文本输出(如用于测试),olap4j 本身带了一个格式化输出实现:

 

CellSetFormatter formatter = new RectangularCellSetFormatter(false);

formatter.format(cellSet, new PrintWriter(System.out, true));

 

JSP 标签

Mondrian 提供了一个jsp 标签库来执行查询、输出HTML。标签库只有两个标签:query 和transform,前者执行一个MDX 查询,后者通过XSLT 转换成HTML 表格输出。
query 标签只有两个属性,name 和resultCache,resultCache 参数是可选的,控制在不同的请求是否重新执行查询(这在开发时有用)。
transform 标签只有三个属性query、xsltURI 和xsltCache。query 属性引用一个先前
定义的query。xsltCache 属性是可选的。

以下是例子:

 

<mdx:query name="query1" resultCache="true">

select

{[Measures].[Unit Sales], [Measures].[Store Cost],

[Measures].[Store Sales]} on columns,

CrossJoin(

{ [Promotion Media].[All Media].[Radio],

[Promotion Media].[All Media].[TV],

[Promotion Media].[All Media].[Sunday Paper],

[Promotion Media].[All Media].[Street Handout] },

[Product].[All Products].[Drink].children) on rows

from Sales

where ([Time].[1997])

</mdx:query>

<mdx:transform query="query1" xsltURI="/WEB-INF/mdxtable.xsl"

xsltCache="false"/>

 

XMLA

XMLA 是一套标准,定义了在WEB 来使用OLAP 服务的标准方式。它基于HTTP、XML、SOAP 这些开放的标准,独立与特定的语言和平台。它通过发送SOAP 消息,消息中包含MDX 语句来执行查询。
XMLA 的内容
XMLA 仅仅有两个SOAP 方法:Execute 和Discover。
Execute 方法有两个参数:

  • Command 要执行的命令,可以是MDX, SQL 和DMX(Data Mining 语言,当然Mondrian不支持数据挖掘)
  • Properties 命令参数的XML 列表

Execute 命令的返回结果是多维数据集或表格化行集。
Discover 方法设计用来整合各种各样获取元数据的发现方法,它的返回值是行集。

具体略。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值