Mondrian学习(2):什么是mondrian

    mondrian是一个开放源码的Rolap服务器,使用java技术开发。它实现了xmla和jolap规范。并且支持由Microsoft,Hypeion等公司研究的多维查询表达式MDX(类似于sql)。

    到目前关于Mondrian的资料还是相对较少。多数就是对官网上的demo基础的使用并没有具体在项目中的具体集成和使用。

    Mondrian下载:https://sourceforge.net/projects/mondrian/ 

   Mondrian API:https://mondrian.pentaho.com/documentation/architecture.php

   先来一张官方的图:

整个Mondrian分为四层:

    1.表现层(presentation layer):

从最上面可以看到mondrian的入口

    1).HTTP(JPivot)得到结果,并且官方提供的war包就是就是基于此的,但是通过资料的查新这个现实层以及停止维护已经很老并且并不是基于mvc模式开发,舍弃掉。

    2).XML/HTTP也是官方提供的,舍弃。

    3).JAVA通过API调用得到结果,这个正是我想要的,通过集成到java web中展示层则使用echarts等工具。

    2. 计算层(dimmensinal layer):分析和校验MDX语句,并且将分析后的语句发送到聚集层进行聚集

    3.聚集层(star layer):聚集层是一个缓冲层对一些操作过的数据进行缓存提供系统的性能。

    4.存储层:提供聚集的元数据,可以在多台机器上。

    通过上面可以了解到我们接触到比较多的是展示层和存储层和计算层的MDX语句的编写。

先通过Java做一个demo 吧。

先准备环境:搭建存储层

表结构:

需要的jar包


需要用到的聚集文件:

<Schema name="db">
    <!--创建一个数据立方体-->
    <Cube name="Sales" visible="true" cache="true" enabled="true">
        <!--事实表 使用name指定表名-->
        <Table name="sale">
        </Table>
        <!--维度1 foreignKey 事实表中的外键id name维度名称  -->
        <Dimension visible="true" foreignKey="cusId" highCardinality="false" name="cusGender">
            <!--维度细分的层次 allMemberName 所有维度的名称 primaryKey维度表的主键 hasAll是否包含所有维度-->
            <Hierarchy visible="true" hasAll="true" allMemberName="allGender" primaryKey="cusId">
                <!---->
                <Table name="customer">
                </Table>
                <!--定义层次的水平,column 维度表的那一列 .... -->
                <Level name="gender" visible="true" column="gender" type="String" uniqueMembers="false" levelType="Regular" hideMemberIf="Never">
                </Level>
            </Hierarchy>
        </Dimension>
        <Dimension visible="true" foreignKey="proId" highCardinality="false" name="proType">
            <!--primaryKey 维度主键  primaryKeyTable维度主键对应的表-->
            <Hierarchy visible="true" hasAll="true" allMemberName="allPro" primaryKey="proId" primaryKeyTable="product">
                <!--两张表外键关系-->
                <Join leftKey="proTypeId" rightKey="proTypeId">
                    <Table name="product">
                    </Table>
                    <Table name="producttype">
                    </Table>
                </Join>
                <!--具体的维度 -->
                <Level name="proTypeId" visible="true" table="producttype" column="protypeid" nameColumn="protypename" type="String" uniqueMembers="true" levelType="Regular" hideMemberIf="Never">
                </Level>
                <Level name="proId" visible="true" table="product" column="proId" nameColumn="proName" type="String" uniqueMembers="true" levelType="Regular" hideMemberIf="Never">
                </Level>
            </Hierarchy>
        </Dimension>
        <!--事实表 aggregator 统计时使用的函数 sum累加 formatString 格式化字符串,可以格式化类似Money、时间之类的格式-->
        <Measure name="numb" column="number" datatype="Numeric" aggregator="sum"></Measure>
        <Measure name="totalSale" formatString="¥#,##0.00" aggregator="sum">
            <!--sql 片段-->
            <MeasureExpression>
                <SQL dialect="generic">
                    <![CDATA[(unitPrice*number)]]>
                </SQL>
            </MeasureExpression>
        </Measure>
        <CalculatedMember name="averPri" dimension="Measures">
            <Formula>
                <![CDATA[[Measures].[totalSale] / [Measures].[numb]]]>
            </Formula>
            <CalculatedMemberProperty name="FORMAT_STRING" value="¥#,##0.00">
            </CalculatedMemberProperty>
        </CalculatedMember>
    </Cube>
</Schema>

Java demo文件  为了方便就直接写的main

package com.yanghs.test;

import mondrian.olap.Result;
import org.apache.log4j.PropertyConfigurator;
import org.olap4j.*;
import org.olap4j.metadata.Member;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author yanghs
 * @Description:
 * @date 2018/4/21 11:49
 */
public class demo1 {
    public static void main(String[] args) throws FileNotFoundException {
        OlapConnection conn = null;
        try {
            InputStream is = new BufferedInputStream(new FileInputStream("G:\\mycode\\mondriandemo\\src\\main\\javacode\\com\\yanghs\\test\\log4j.properties"));
            PropertyConfigurator.configure( is);
            conn= getConnection(
                    //URL协议
                    "jdbc:mondrian:"
                            //连接数据源的JDBC连接
                            + "Jdbc='jdbc:mysql://localhost:3306/testdb?user=root&password=123456&useUnicode=true&characterEncoding=utf8';"
                            //数据模型文件
                            + "Catalog=G:\\mycode\\mondriandemo\\src\\main\\javacode\\com\\yanghs\\test\\qiuschema.xml;"
                            //连接数据源用到的驱动
                            + "JdbcDrivers=com.mysql.jdbc.Driver;");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //查询语句
        String mdx="SELECT {[Measures].[numb]} ON 0,{[proType].[proId].members} on 1 FROM [Sales]";
        CellSet cs= null;
        try {
            cs = getResultSet(mdx, conn);
        } catch (OlapException e) {
            e.printStackTrace();
        }
        /*遍历结果*/
        if(cs.getAxes().size()>1){
            for (Position row : cs.getAxes().get(1)) {
                for (Position column : cs.getAxes().get(0)) {
                    for (Member member : row.getMembers()) {
                        System.out.println("rows:"+member.getUniqueName());
                    }
                    for (Member member : column.getMembers()) {
                        System.out.println("columns:"+member.getUniqueName());
                    }
                    final Cell cell = cs.getCell(column, row);
                    System.out.println("values:"+cell.getValue());
                    System.out.println();
                }
            }
        }else{
            for(Position column:cs.getAxes().get(0))
            {
                for(Member member:column.getMembers()){
                    System.out.println("columns:"+member.getUniqueName());
                }
                Cell cell=cs.getCell(column);
                System.out.print("values:"+cell.getValue());
                System.out.println();
            }
        }

    }

    /**
     * 得到连接
     * @param url
     * @return
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    public static OlapConnection getConnection(String url) throws ClassNotFoundException, SQLException {
        Class.forName("mondrian.olap4j.MondrianOlap4jDriver");
        Connection connection = DriverManager.getConnection(url);
        return connection.unwrap(OlapConnection.class);
    }

    /**
     * 得打查询的结果
     * @param mdx
     * @param conn
     * @return
     * @throws OlapException
     */
    public static CellSet getResultSet(String mdx, OlapConnection conn) throws OlapException {
        OlapStatement statement = conn.createStatement();
        CellSet cellSet = statement.executeOlapQuery(mdx);
        return cellSet;
    }
}

运行结果

rows:[proType].[shiwu].[baozi]
columns:[Measures].[numb]
values:3.0

rows:[proType].[shiwu].[mantou]
columns:[Measures].[numb]
values:3.0

rows:[proType].[diannao].[hp]
columns:[Measures].[numb]
values:58.0

rows:[proType].[diannao].[lenovo]
columns:[Measures].[numb]
values:77.0

rows:[proType].[diannao].[asus]
columns:[Measures].[numb]
values:54.0

rows:[proType].[jiaju].[zhuozi]
columns:[Measures].[numb]
values:36.0

rows:[proType].[jiaju].[yizi]
columns:[Measures].[numb]
values:57.0

通过日志文件打印了查询sql语句,olap引擎把mdx语句翻译为sql查询数据。

通过上面mdx语句执行是不是很像jdbc的编程,其实mondrian做的事情就是把mdx语句翻译为sql语句,而mdx语句是专门用来做多维数据分析。

这个项目很小就不上传了,建表语句和pom.xml 及我的maven下载不到的jar包。

下载:https://pan.baidu.com/s/1OiYEE1aaWYEiJhZr6elhqw




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Mondrian Loop是一款基于荷兰艺术家皮特·蒙德里安的抽象艺术风格而设计的游戏。这款游戏包含了蒙德里安经典作品中的几何形状和颜色元素,让玩家在游戏中能够感受到蒙德里安独特的艺术风格。 在Mondrian Loop中,玩家需要通过旋转、移动和调整形状的位置来重新排列画面中的几何图形,以达到完美的平衡和对称。游戏中的每个关卡都会提供不同的挑战,玩家需要思考如何将图形组合在一起,使得整个画面看起来和谐统一。 这款游戏不仅仅是简单的图形排列,还结合了音乐和声效,让玩家能够陷入艺术的氛围中。通过与画面上的图形交互,玩家可以感受到蒙德里安艺术作品中的节奏感和平衡感,进一步理解和欣赏他独特的艺术风格。 Mondrian Loop不仅是一款娱乐游戏,更是一种艺术体验。通过与蒙德里安的作品互动,玩家可以进一步了解他的艺术创作理念和风格特点。同时,这款游戏也提供了一个创造和表达自己的空间,玩家可以根据自己的想法和审美创作一副独特的艺术作品。 总之,Mondrian Loop是一款将蒙德里安的艺术与游戏相结合的创新之作。通过解谜和互动的方式,玩家可以在游戏中感受到蒙德里安的艺术魅力,并且创造出属于自己的独特艺术作品。 ### 回答2: Mondrian Loop是指一种在绘画和设计中经常被使用的艺术概念和技法。这个概念源于荷兰艺术家皮特·蒙德里安(Piet Mondrian)的作品,他以抽象的、几何的方式表达了对自然和现实的热爱。 Mondrian Loop 集中表现了蒙德里安的风格和创作思想。这个概念揭示了对事物本质的追求,以及通过线条、颜色和构图的组合来呈现平衡和和谐的艺术作品。 在Mondrian Loop中,主要的元素是直线和正方形。通过严格的几何形状与明亮的原色,蒙德里安创造出了简洁、纯粹的艺术作品。他的作品中经常可以看到黑色和白色的直线,将画布分割为各个区块,并填充上红色、黄色和蓝色等原色。通过对这些基本元素的运用,他创造出了高度简化的形式和节奏感,同时又保持了作品内部的平衡和对称。 Mondrian Loop不仅仅是对艺术形式的追求,更是一种对和谐和秩序的表达。它反映了蒙德里安对宇宙和人类关系的思考,以及对理想社会的探索。通过追寻本质和平衡的艺术形式,他试图传达人类内心更深层次的渴望和追求。 总之,Mondrian Loop是一种以直线和正方形为主要表现形式的艺术概念,它凸显了蒙德里安在绘画和设计中的独特风格。这个概念不仅仅是对形式和色彩的追求,更是一种对和谐、平衡和秩序的表达,反映了蒙德里安对宇宙和理想社会的思考。 ### 回答3: "Mondrian loap"是一种错误的拼写,似乎是指的荷兰画家皮特·蒙德里安(Piet Mondrian)和他的抽象绘画风格。蒙德里安是20世纪抽象艺术的先驱之一。他在艺术中的风格独特,以直线和矩形元素的平面排列为特征,通过使用基本的几何形状和纯粹的颜色来表达他对世界的理解。 蒙德里安的作品主要由黑、白和原色构成。他将画布分割成不同大小的矩形块,用红、黄和蓝来填充。这种风格被称为“新现实主义”,强调了对基本形状和颜色的探索,以及对自然和现实的简化和抽象。 蒙德里安的艺术作品被广泛认为是抽象艺术的重要里程碑,对后来的艺术家和设计师产生了深远的影响。他的作品传达了平衡、秩序和和谐的观念,同时也表达了一种对纯粹和简单的追求。他的风格也被认为是现代设计和建筑的重要参考。 总的来说,蒙德里安的作品以它独特的几何图案和纯粹的色彩而闻名,它们代表了一种追求简单和平衡的艺术风格。蒙德里安的贡献为抽象艺术的发展做出了重要的贡献,并留下了对艺术和设计的持久影响。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值