前面讲了通过类似jdbc编程的方式来使用mondrian多维分析工具,显然有很多弊端。
1.这种方式通过字符串中的key-value把数据库连接,模型文件,数据库驱动都写死了。并且每次获取一个连接都要getconnetion一次。
2.一般的java web项目通过spring管理各种bean 包括数据源。这里得到连接的方法不能很好的与spring连起来
3.项目中有多个模型文件,每次变换的时候都很麻烦。
带着这些问题开始读了下mondrian的源码,在包下发现了DriverManager类 中有一个getConnection方法
package mondrian.olap;
public static Connection getConnection(PropertyList properties, CatalogLocator locator, DataSource dataSource) {
String provider = properties.get("PROVIDER", "mondrian");
if (!provider.equalsIgnoreCase("mondrian")) {
throw Util.newError("Provider not recognized: " + provider);
} else {
String instance = properties.get(RolapConnectionProperties.Instance.name());
MondrianServer server = MondrianServer.forId(instance);
if (server == null) {
throw Util.newError("Unknown server instance: " + instance);
} else {
if (locator == null) {
locator = server.getCatalogLocator();
}
if (locator != null) {
String catalog = properties.get(RolapConnectionProperties.Catalog.name());
properties.put(RolapConnectionProperties.Catalog.name(), locator.locate(catalog));
}
RolapConnection connection = new RolapConnection(server, properties, dataSource);
server.addConnection(connection);
return connection;
}
}
}
通过断点调试:
PropertyList是配置文件key-value
CatalogLocator与模型文件有关
DataSource 这就是直接可以传进来的数据源了,因为采用了jdbc的方式这里传进来为null
1、通过查阅mondrian api 配置文件mondrian.properties 那么ProperList的key-value就是从这里面得到的,通过MondrianProperties类得到证实
private MondrianProperties() {
super(new FilePropertySource(new File("mondrian.properties")));
this.populate();
}
创建配置文件mondrian.properties
#mondrian 配置文件 2018年5月2日10:49:14
#api参考地址 https://mondrian.pentaho.com/documentation/configuration.php
#是否打印生成的sql 默认false
mondrian.rolap.aggregates.generateSql = true
#mdx语句是否区分大小写 默认false
mondrian.olap.case.sensitive = false
Provider = Mondrian
#模型文件缓存池
UseSchemaPool = false
#忽略不重要的错误
IgnoreError = false
#连接池
connectionPooling = false
配合MondrianProperties使用配置文件
MondrianProperties properties = MondrianProperties.instance();便会去加载配置文件;
配置文件解决
2、CatalogLocator 这个文件一时摸不到头,是一个接口并且只要一个方法locate。查看各个实现类
除了ServletContextCatalogLocator这个文件对方法有具体实现并且是与servlet上下文相关的,其他都是直接return。主要看了ServletContextCatalogLocator.locate方法的具体实现发现是查找文件并且返回路径
public String locate(String catalogPath) {
if (catalogPath != null && catalogPath.startsWith("/")) {
try {
URL url = this.servletContext.getResource(catalogPath);
if (url == null) {
url = this.servletContext.getResource("/");
url = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile() + catalogPath.substring(1));
}
catalogPath = url.toString();
} catch (MalformedURLException var3) {
;
}
}
return catalogPath;
}
这就是在找模型文件并且返回真实路径为了安全我把模型文件放在了web-inf下的mondrian文件夹路径参考为
/WEB-INF/mondrian/Sales.xml
3、DataSource这个最简单 spring里面直接拿一个就行。
终于集齐了该召唤神龙了:
private Connection getConnection() throws OlapException {
mondrian.olap.Util.PropertyList properties =new mondrian.olap.Util.PropertyList();
properties.put(RolapConnectionProperties.Provider.name(), mondrianProperties.get("Provider").toString());
properties.put(RolapConnectionProperties.Catalog.name(), catalog);
properties.put(RolapConnectionProperties.PoolNeeded.name(), mondrianProperties.get("connectionPooling").toString());
properties.put(RolapConnectionProperties.UseSchemaPool.name(), mondrianProperties.get("UseSchemaPool").toString());
properties.put(RolapConnectionProperties.Locale.name(), LOCALE);
properties.put(RolapConnectionProperties.Ignore.name(), mondrianProperties.get("IgnoreError").toString());
mondrian.spi.CatalogLocator catalogLocator;
if(servletContext!=null) {
catalogLocator = new ServletContextCatalogLocator(servletContext);
}else{
catalogLocator=null;
}
//RolapConnection rolapConnection = (RolapConnection) DriverManager.getConnection(properties, catalogLocator, dataSource);
Connection monConnection = DriverManager.getConnection(properties, catalogLocator, dataSource);
if (monConnection == null)
{
String err = "Could not create Mondrian connection:" + properties;
logger.error(err);
throw new OlapException(err);
}
return monConnection;
}
进行了简单的封装,解决了得到连接的问题。到这也就基本集成到web项目中。