遇到问题,想查看mondrian 带的 example,那就部署一个mondrian 带的footmart例子
olap4j包中有个:
- org.olap4j.query - Programmatic Query Model
我理解就是个简化mdx查询的工具,不过官方介绍说不支持全部mdx语句。
下面小试一把:
// olap4j的mdx接口,是一个jdbc实现,推荐
System.out.println("\r\n===================olap4j接口==================");
String mdxStr = "select {[年].Members} on columns,{[组织].Members} on rows from 模型一";
// 建立连接
String strUrl = "jdbc:mondrian:";
strUrl += "Jdbc=" + url;
strUrl += ";JdbcUser=" + userName;
strUrl += ";JdbcPassword=" + password;
// strUrl += ";Catalog=" + xmlFile;
strUrl += ";CatalogContent=" + getCatalogContent();
Class.forName("mondrian.olap4j.MondrianOlap4jDriver");
Connection olap4jConn = DriverManager.getConnection(strUrl);
OlapConnection olapConn = (OlapConnection) olap4jConn.unwrap(OlapConnection.class);
NamedList<Cube> cubes =
olapConn.getOlapSchema().getCubes();
Cube cube = cubes.get("模型一");
Query myQuery =
new Query("model1Query", cube);
myQuery.execute();
System.out.println("------------myQuery------------:"+myQuery);
QueryDimension productDim = myQuery.getDimension("年");
QueryDimension storeDim = myQuery.getDimension("组织");
//QueryDimension timeDim = myQuery.getDimension("Time");
myQuery.getAxis(Axis.COLUMNS).addDimension(productDim);
myQuery.getAxis(Axis.ROWS).addDimension(storeDim);
//myQuery.getAxis(Axis.FILTER).addDimension(timeDim);
myQuery.validate();
System.out.println(
myQuery.getSelect().toString());
String s=myQuery.getSelect().toString();
CellSet cellSet = myQuery.execute();
// 输出结果
CellSetFormatter formatter = new RectangularCellSetFormatter(false);
formatter.format(cellSet, new PrintWriter(System.out, true));
这个工具能生成mdx,查询。生成的语句如下:
SELECT
{[年].[年]} ON COLUMNS,
{[组织].[组织]} ON ROWS
FROM [模型一]
但执行这个语句,报错:
Caused by: mondrian.olap.MondrianException: Mondrian Error:No function matches signature '{<Level>}'
是的,我前面手工写的语句是:{[年].members},好使,怎么办,装mondrain的例子吧,看看有啥不同。
先来个简单的,配置foodmart access数据库,配置odbc数据源,费了好长时间,还是连接有问题,也许是连接url写的有问题,
果断换mysql吧。
MYSQL:
mysql 命令行登录模式如下:
mysql -h localhost -u root -p password
报错:mysql ERROR 1049 (42000): Unknown database
找到https://blog.youkuaiyun.com/dongdekun369/article/details/47175295文章,查询得知:
mysql -h localhost -u root -ppassword
-p和密码是连在一起的,赶紧一试,果然可以登陆!
唉.....我真是愤慨啊!!!
妈的啊!一个不小心,被误导了这么久。我当初怎么查到的尽是些-p后面带个空格的格式呢。
PS:-r后面可以紧跟用户名,也可以加个空格,但密码后面一定不能加空格。
如果想省略-h,好像还需要授权。
网上download一个foodmart_mysql.tar.gz,mysql中创建footmart数据库,运行foodmart_mysql.sql,foodmart数据库安装ok。
还要老老实实重新部署一个foodmart应用。
指定tomcat的jdk,修改tomcat启动窗口title
我的机器上部署了太多tomcat,没做标志,把tomcat启动的命令窗口换个名字,标记一下:
在tomcat的catalina.bat文件中,修改:
if "%TITLE%" == "" set TITLE=foodmart_8068
同时,在这个文件开头修改:
set JAVA_HOME=C:\Program Files\Java\Java6\jdk1.6
set JRE_HOME=C:\Program Files\Java\Java6\jre6
copy mondrian.war 到tomcat下。借用老外的一张图:
浏览器运行:
剩下的还得配置数据库连接。
浏览到Mondrian的应用程序查询文件夹,您可以在其中找到几个示例jsp文件。在这里,我打开我的E:\olap\service\tomcat6.0.20_8068\webapps\mondrian\WEB-INF\queries文件夹,找到以下jsp文件:
- fourheir.jsp
- mondrian.jsp
- colors.jsp
- arrows.jsp
<jp:mondrianQuery id="query01" jdbcDriver="com.mysql.jdbc.Driver" jdbcUrl="jdbc:mysql://localhost:3306/foodmart?characterEncoding=utf8&useSSL=true" catalogUri="/WEB-INF/queries/FoodMart.xml"
jdbcUser="root" jdbcPassword="****" connectionPooling="false">
浏览当地的蒙德里安主机地址:http:// localhost:8080 / mondrian,选择第一个mondrian示例“ JPivot pivot table ”。
由于蒙德里安需要在视图出现之前填充其初始缓存,因此需要一些时间。
然后,您将看到一个可以分层方式钻取的表和一个包含配置图标的标题工具栏。
mondrian例子程序完成!
整个配置过程,参照
http://hamdihasnaoui.weebly.com/tutorials/category/mondrian 完成,一次成型!
网上一些用mondrian命令行安装数据库等,老夫没有尝试,年纪大,懒得看。
foodmart数据库脚本上传了,不晓得为什么要5分,我本来只想定1分的。
回到原本的问题,要看看我用olap4j 的.query,我错在哪呢?
还是写个测试代码跑一下吧:
public class TestMondrian_footmart1 {
// 数据库连接信息,这里用的mysql
private static String url="jdbc:mysql://localhost:3306/foodmart?characterEncoding=utf8&useSSL=true";
private static String userName = "root";
private static String password = "***";
private static String xmlFile = "FoodMart.xml";
public static void main(String[] args) throws Exception {
// 建立连接
String strUrl = "jdbc:mondrian:";
strUrl += "Jdbc=" + url;
strUrl += ";JdbcUser=" + userName;
strUrl += ";JdbcPassword=" + password;
// strUrl += ";Catalog=" + xmlFile;
strUrl += ";CatalogContent=" + getCatalogContent();
Connection connection =
DriverManager.getConnection(strUrl);
OlapConnection olapConn = (OlapConnection) connection.unwrap(OlapConnection.class);
}
/**
* 初始化数据库,建表
* @throws Exception
*/
private static void initDB() throws Exception {}
private static String getCatalogContent() throws Exception {
//InputStream inputStream = mondrian.olap.Util.readVirtualFile(xmlFile);
InputStream inputStream =null;
try {
inputStream=mondrian.olap.Util.readVirtualFile(xmlFile);
final byte[] bytes = Util.readFully(inputStream, 1024);
// 下面是mondrian原来的实现,由于byte被强制转化为char,汉字全为乱码,故将这段处理处理掉。
// final char[] chars = new char[bytes.length];
// for (int i = 0; i < chars.length; i++) {
// chars[i] = (char) bytes[i];
// }
String s=new String(bytes, "UTF-8");
return s;
}catch(Exception e){
e.printStackTrace();
return "";
}
finally {
if (inputStream != null) {
inputStream.close();
}
}
}
}
嗯,报错:
xception in thread "main" java.lang.RuntimeException: quoted value ended too soon, at position 5545 in 'Jdbc=jdbc:mysql://localhost:3306/foodmart?characterEncoding=utf8&useSSL=true;JdbcUser=root;JdbcPassword=***;CatalogContent=<?xml version="1.0"?>
<Schema name="FoodMart">
...
</Schema>
'
at mondrian.olap.Util$ConnectStringParser.parseValue(Util.java:2848)
at mondrian.olap.Util$ConnectStringParser.parsePair(Util.java:2776)
at mondrian.olap.Util$ConnectStringParser.parse(Util.java:2757)
at mondrian.olap.Util.parseConnectString(Util.java:2736)
at mondrian.olap4j.MondrianOlap4jConnection.<init>(MondrianOlap4jConnection.java:156)
at mondrian.olap4j.FactoryJdbc4Plus$AbstractConnection.<init>(FactoryJdbc4Plus.java:323)
at mondrian.olap4j.FactoryJdbc41Impl$MondrianOlap4jConnectionJdbc41.<init>(FactoryJdbc41Impl.java:118)
at mondrian.olap4j.FactoryJdbc41Impl.newConnection(FactoryJdbc41Impl.java:32)
at mondrian.olap4j.MondrianOlap4jDriver.connect(MondrianOlap4jDriver.java:97)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:270)
at com.muge.as.dao.TestMondrian_footmart1.main(TestMondrian_footmart1.java:54)
猜测是连接字符串符号引起的,检查连接字符串,发现String strUrl = "jdbc:mondrian:"; 里面;写成:。
改为 String strUrl = "jdbc:mondrian;";这个问题消除。
再次运行:报告:No suitable driver found for jdbc:mondrian;JdbcDrivers=...错误。
驱动类没有加载?检查发现没有
Class.forName("mondrian.olap4j.MondrianOlap4jDriver");
加上,再运行测试代码。
Exception in thread "main" java.lang.NoClassDefFoundError: mondrian/xmla/XmlaHandler$XmlaExtra
嗯,我昨天在pom.xml把mondrian3.17 升级为mondrian4.7 版本;查资料得知,xmla,从mondrain 中分离了,试引入新包olap4j-xmla-1.2.jar,pom.xml中添加olap4j-xmla-1.2.jar,再运行,这个错误不报告了
再运行测试,还是报告:No suitable driver found for jdbc:mondrian;JdbcDrivers=...错误。
各种调整connect string,但不奏效;
猜测原因:
- mysql连接有问题,解决办法:先单独测试mysql,单独测试mysql 连接没有问题;
- mondrian 版本问题 解决办法:换个mondrian版本;
换版本idea当中,好像得执行
用如下字符串测试连接:
Provider=mondrian;Catalog=FoodMart.xml;JdbcDrivers=com.mysql.jdbc.Driver;Jdbc=jdbc:mysql://localhost:3306/foodmart?characterEncoding=utf8&useSSL=true;JdbcUser=root;JdbcPassword=**
还是一样报错;这个连接字符串,mysql的url.用户名、密码、JdbcDrivers都不会有错误,难道有错的是Provider=mondrian;Catalog=FoodMart.xml;?这2个部分?Catalog=FoodMart.xml;换成
;CatalogContent=" + getCatalogContent()
还是无效;
先把各jar包导进来,
3、缺少相关jar包 解决办法把各种jar补,,网上说个jar都导入了,还是报一样的错
4、连接字符串错误 解决办法网上查,测试;
上面方式都试过了,花了老夫n多时间,无效,那就调整思路。
1)把mysql数据库导成oracle;
2)换成derby数据库
我这里采用方法1
采用data-integration转换,把foodmart数据库转换为oracle。
再执行测试语句:
报错误:
Exception in thread "main" mondrian.olap.MondrianException: Mondrian Error:Named set in cube 'Sales' has bad formula
...
...
...
Caused by: mondrian.olap.MondrianException: Mondrian Error:Internal error: Populating member cache with members for [[Time].[Year]]; sql=[select "time_by_day"."the_year" as "c0" from "time_by_day" "time_by_day" group by "time_by_day"."the_year" order by "time_by_day"."the_year" ASC NULLS LAST]
plsql测试,确实报表没有找到的错误,把字段名、表名改为大小,plsql测试通过。
通常,表和列不区分大小写,但如果使用引号,则它们将是区分大小写的。自动生成的语句都带了引号;
动手根据提示,在idea中,一阵狂按Ctrl+Shift+U,修改foodmart.xml中相关表名及字段名为大写.和foodmart数据库连接成功!
回到原始的问题,我写的olap4的query有什么错呢?
比较一下例子的数据库表结构、mondrain文件再说。