一,配置
前一阶段对mondrian和jpivot的测试主要建立在jar与war包的基础上面,若要对mondrian源码进行跟踪调试,需要导入mondrian源码包到ide(eclipse)环境中,在构建mondrian源码工程时,要做好相应的准备工作,确保源码不依赖于mondrian.jar包。
由于开源的mondrian3.0.3发布源码工程中没有将全部的源代码提交到工程中, 所以我们构建构成中会缺失一些源代码,但其在工程中提供了mondrian.jar来处理。Mondrian3.0.3的源代码工程中缺失的源代码是由工具自动生产的,并且它提供了生产这些源代码的过程,在build.xml中说明如何生产。下面是简要的工程构建过程说明:
3、在工程属性中指定源代码目录为src/main:右击工程——属性——Java Build Path——选择Source选项卡——删除mondrian工程/src——Add Folder到目录 mondrian工程/src/main;
4、ant运行build.xml文件的prepare,parser,generate.resources,def四个目标过程, 按顺序运行(最好是在命令行下ant整个build文件,在ide中有ant不完全的情况)
(MondrianGuiDef类是因为执行这几个目标过程生成的,要不然就会没有MondrianGuiDef这个类的定义而导致出错,应该还有些其他文件也是运行这四个目标过程生成的,所以这一步很重要)
5、将mondrian.war发布包中的WEB-INF/lib中的jar包全部拷贝到Mondrian工程的lib目录中;
6、根据提示的异常导入必要的jar包文件(最简单的方法是把所有的包导入:右击工程——属性——Java Build Path——选择Libraries选项卡——Add JARs——导入lib下的所有jar,Add External JARS ——导入TOMCAT_HOME/common/lib下的所有的包);
注意:1、最后执行ant完成对工程进行清理处理;
2、如果一切正常,之后则不需要用mondrian.jar文件,可以依此为标准检测是否构建成功。
Mondrian工程构建过程
1、在eclipse中构建一个空的java工程(Mondrian工程);
2、将Mondrian3.0.3的源码压缩包解压,将其内容全部拷贝到Mondrian工程中;
二,在Mondrian工程中构建一个查询进行测试
在查询过程中,Mondrian将mdx语句转换成sql语句,用jdbc访问数据库,实现了立方体的缓存,这是其特点所在。Jpivot并不是对Mondrian提供的公共api的简单调用,而是自己对Mondrian再进行了封装,所以需要对Mondrian的api进行分析,跟踪和调试。
Mondrian提供的一些api用法甚至命名都与jdbc十分相似,执行一次查询的步骤如下所示:(首先导入所需要的包:mondrian.olap.*)
1 新建一个包含main函数测试类,建立一个connection:
Connection conn=DriverManager.getConnection(String,BOOl);
测试的String的内容为:
Access:
"Jdbc=jdbc:odbc:MondrianFoodMart;Catalog=file:///D:/workspace/mondrian工程/webapp/WEB-INF/queries/FoodMart.xml;JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver; "
在String中定义了数据库连接的参数,以及Schema文件的路径(CataLog)。
注意:
1 Provider=mondrian这一句是必须的,mondrian生成connection的时候对provider的值进行了单独的检查,没有这一句或者provider为其他值,都会触发异常;
2 第二个参数定义CataLog,若在String中已经定义,值为null(记住要把FoodMart.xml拷贝到D:/workspace/mondrian工程/webapp/WEB-INF/queries目录下);
3 Mondrian2.x和Mondrian3.x有较大改动,对于getConnection()函数而言,mondrian3.x只有两个参数,2.x则有三个参数。
2 定义查询语句:
String queryStr ="select {[Measures].[Unit Sales]} on columns "+
"from Sales"
注意:查询语句必须遵守mdx语法;
3 利用connection生成一个Query对象:
Query query = conn.paseQuery(queryStr);
4 执行查询得到结果:
Result result = conn.execute(query);
5 控制台打印结果:
PrintWriter pw = new PrintWriter(System.out);
result.print(pw);
pw.flush();
综合起来就是:
import mondrian.olap.*;
import java.io.*;
public class MyTest {
public static void main(String[] args)
{
Connection conn=DriverManager.getConnection("Provider=mondrian;"+
"Jdbc=jdbc:odbc:MondrianFoodMart;"+
"Catalog=file:///D:/workspace/mondrian工程/webapp/WEB-INF/queries/FoodMart.xml;"+
"JdbcDrivers=sun.jdbc.odbc.JdbcOdbcDriver; ",null);
String queryStr ="select {[Measures].[Unit Sales]} on columns "+
"from Sales";
Query query=conn.parseQuery(queryStr);
Result result=conn.execute(query);
PrintWriter pw = new PrintWriter(System.out);
result.print(pw);
pw.flush();
System.out.println("successful!");
}
}
控制台输出结果为:
Axis #0:
{}
Axis #1:
{[Measures].[Unit Sales]}
Row #0: 266,773
successful!
注意:1 最后一句pw.flush()很重要,虽然在Mondrian文档中未加说明,但如果没有这一句,在控制台下看不到结果
2 轴和单元值是分开打印的;