gdufo

           

          2016年2月6日

          Mondrian 使用教程

          http://blog.csdn.net/evangel_z/article/details/29585571

          通過本教程,您將了解到什么是Mondiran,及如何將mondrian支持添加到您的Java Web項目中。

          在閱讀本教程之前,您可能需要掌握以下概念:

          OLAP(聯機分析處理On-Line Analytical Processing),您可以通過閱讀ROLAP的概念.pptx來了解OLAP

          MDX多維表達式,您可以通過閱讀MDX的基本語法及概念.pptx來了解MDX


          1. Mondrian是什么?

          Mondrian是一個開源項目。一個用Java寫成的OLAP引擎。它用MDX語言實現查詢,從關系數據庫(RDBMS)中讀取數據。然后經過Java API以多維的方式對結果進行展示。

          Mondrian的使用方式同JDBC驅動類似。可以非常方便的與現有的Web項目集成

          1.1 Mondrian的體系結構(Architecture)

          Mondrian OLAP 系統由四個層組成; 從最終用戶到數據中心, 順序為: 
          1.1.1 表現層(the presentation layer)
          1.1.2 維度層(the dimensional layer)
          1.1.3 集合層(the star layer)
          1.1.4 存儲層(the storage layer)
          結構圖如下:


          1.1.1 表現層(the presentation layer)

          表現層決定了最終用戶將在他們的顯示器上看到什么, 及他們如何同系統產生交互。

          有許多方法可以用來向用戶顯示多維數據集, 有 pivot 表 (一種交互式的表), pie, line 和圖表(bar charts)。它們可以用Swing 或 JSP來實現。

          表現層以多維"文法(grammar)(維、度量、單元)”的形式發出查詢,然后OLAP服務器返回結果。

          1.1.1.1 Jpivot表現層

          JPivot 是Mondrian的表現層TagLib,一直保持著良好的開發進度。

          您可以通過訪問jpivot的官方網站http://jpivot.sourceforge.net/以獲得更多的幫助及支持

          jpivot使用XML/ XSLT渲染OLAP報表:

          JPivot 使用 WCF (Web Component Framework)  ,基于XML/XSLT來渲染Web UI組件。這使它顯得十分另類。不過,OLAP報表這種非常復雜但又有規律可循的東西,最適合使用XSLT來渲染。

          jpivot完全基于JSP+TagLib:

          JPivot另外一個可能使人不慣的地方是它完全基于taglib而不是大家熟悉的MVC模式。

          但它可以很方便的將多維數據展示給最終用戶,如下表格:


          jpivot其實是一個自定義jsp的標簽庫。它基于XML/XSLT配置來生成相應的html。所幸的是,我們并不需要了解太多關于這方面的內容,我們只要掌握相應jsp標簽的使用即可。

          在本教程的實例中,我們將會對一些常用到的jpivot標簽進行講解。

          您還可以通過漢化WEB-INF/jpivot下的xml文件來完成對jpivot的漢化工作

          1.1.2 維度層(the dimensional layer)

          維度層用來解析、驗證和執行MDX查詢要求。

          一個MDX查詢要通過幾個階段來完成:首先是計算坐標軸(axes),再者計算坐標軸axes 中cell的值。

           為了提高效率,維度層把要求查詢的單元成批發送到集合層,查詢轉換器接受操作現有查詢的請求,而不是對每個請求都建立一個MDX 聲明。

          1.1.3 集合層(the star layer)

          集合層負責維護和創建集合緩存,一個集合是在內存中緩存一組單元值, 這些單元值由一組維的值來確定。

          維度層對這些單元發出查詢請求,如果所查詢的單元值不在緩存中,則集合管理器(aggregation manager)會向存儲層發出查詢請求

          1.1.4 存儲層(the storage layer)

          存儲層是一個關系型數據庫(RDBMS)。它負責創建集合的單元數據,和提供維表的成員。

          1.2 API

          Mondrian 為客戶端提供一個用于查詢的API

          因為到目前為止,并沒有一個通用的用于OLAP查詢的API,因此Mondrian提供了它私有的API.

          盡管如此,一個常使用JDBC的人將同樣發現它很熟悉.不同之處僅在于它使用的是MDX查詢語言,而非SQL

          下面的java片段展示了如何連接到Mondrian,然后執行一個查詢,最后打印結果.

          1. import mondrian.olap.*;  
          2.     import java.io.PrintWriter;  
          3.     Connection connection = DriverManager.getConnection("Provider=mondrian;"   
          4.             +"Jdbc=jdbc:odbc:MondrianFoodMart;"   
          5.             +"Catalog=/WEB-INF/FoodMart.xml;",null,false);  
          6.     Query query = connection.parseQuery("SELECT {[Measures].[Unit Sales], [Measures].[Store Sales]} on columns,"   
          7.             +" {[Product].children} on rows "   
          8.             +"FROM [Sales] " +"WHERE ([Time].[1997].[Q1], [Store].[CA].[San Francisco])");  
          9.     Result result = connection.execute(query);  
          10.     result.print(new PrintWriter(System.out));  

          與JDBC類似,一個Connection由DriverManager創建,Query 對象類似于JDBC 的Statement,它通過傳遞一個MDX語句來創建.Result對象類似于JDBC的ResultSet,只不過它里面保存的是多維數據

          您可以通過查看Mondrian幫助文檔里的javadoc來獲取更多關于Mondrian API的資料

          通過上面的介紹,您應該對mondrian的體系有一個基本的了解。

          下面我們將通過一個簡單的例子來加深您的理解。


          2. 一個簡單的Mondrian例子

          現在讓我們用一個簡單的例子來說明將Mondrian支持添加到您java web的具體步驟。

          2.1 準備開發工具及環境

          本測試需要的環境:
          操作系統:Windows 2000;
          Web服務器:tomcat6.0;
          關系數據庫:sql server 2000;
          開發工具:eclipse + myeclipse;
                JDBC驅動:jtds-1.2.2;

                   您可以在http://tomcat.apache.org/上下載到tomcat的最新版本及幫助;
                您可以在http://www.myeclipseide.com/上下載到myeclipse的最新版本及相應的eclipse開發平臺版本

          2.2 準備Mondrian資源:

          http://sourceforge.net/projects/mondrian/下載Mondrian的最新版本(目前版本為3.0,大約有50M+大小)。


          2.3 創建項目

          啟動eclipse。

          在eclipse中新創建一個web項目,名為Tezz。注意需要加入JSTL支持。

          具體步驟如下:

          2.3.1  打開新建web項目對話框



          一個新項目Tezz的文件結構如下:


          2.4 添加必須的文件

          將下載的壓縮包進行解壓。完成后,進入文件夾可以看到如下目錄結構。雙擊進入lib文件夾。


          Lib文件夾有如下內容:注意到這里的mondrian.war文件是一個可直接布署的項目,我們需要將它解壓,然后從中取出我們所需要的文件。(建議將其擴展名改成zip,然后直接右鍵解壓)


          進入解壓后的文件夾,選中jpivot、wcf二個文件夾及busy.jsp、error.jsp、testpage.jsp三個文件,我們需要將這些資源復制到我們測試項目的WebRoot文件夾中。按ctrl+C鍵復制。


          注:jpivot、wcf這兩個文件夾包含mondrian使用的圖像和css文件。Busy.jsp顯示等待頁面、error.jsp顯示出錯頁面、testpage.jsp這文件的用處將在后面介紹。

          切換到eclipse界面,在我們的Tezz項目的WebRoot文件夾處右擊鼠標,在彈出的菜單中選擇Paste(粘貼)即可


          粘貼完成后的項目結構如下


          注意:因為我們還未將所有資料復制到項目中,因此eclipse會顯示錯誤圖標

          最后進入WEB-INF文件夾(在上面步驟中解壓的項目文件mondrian.war里),選中jpivot、lib、wcf這三個文件夾,同樣需要復制它們到測試項目的WEB-INF文件夾中。


          Jpivot、wcf這兩個文件夾包含jpivot和wcf用于生成用戶界面的配置文件(*.xml、*.xsl)及標簽文件(*.tld)的定義。Lib文件夾包含的是mondrian所要用的java包。

          切換到eclipse界面,在我們的Tezz項目的WebRoot文件夾處右擊鼠標,在彈出的菜單中選擇Paste(粘貼)


          至此Mondrian的支持添加完畢,下面我們將配置web.xml,讓我們的項目能夠使用到mondrian的功能。

          2.5 配置web.xml

          用eclipse打開我們在上面解壓的布署項目的WEB-INF/web.xml文件


          過濾器(filter)

          復制如下所示的xml代碼到我們測試項目Tezz的web.xml文件中。

          作用:這個過濾器在訪問/testpage.jsp前被調用。它被設計成jpivot的前端控制器,用于判斷并將用戶的請求發送到某個頁面。

          注:在實際項目中可以使用您自己定義的servlet或使用其他技術來替代它以提供更多的功能

          1.  <filter>  
          2.     <filter-name>JPivotController</filter-name>  
          3.     <filter-class>com.tonbeller.wcf.controller.RequestFilter</filter-class>  
          4.     <init-param>  
          5.       <param-name>indexJSP</param-name>  
          6.       <param-value>/index.html</param-value>  
          7.       <description>如果這是一個新的會話,則轉到此頁面</description>  
          8.     </init-param>  
          9.     <init-param>  
          10.       <param-name>errorJSP</param-name>  
          11.       <param-value>/error.jsp</param-value>  
          12.       <description>出錯時顯示的頁面</description>  
          13.     </init-param>  
          14.     <init-param>  
          15.       <param-name>busyJSP</param-name>  
          16.       <param-value>/busy.jsp</param-value>  
          17.       <description>這個頁面用于當用戶點擊一個查詢時,在這個查詢還未將結果還回給用戶時所顯示的界面</description>  
          18.     </init-param>  
          19. </filter>  
          20.   
          21.   <filter-mapping>  
          22.     <filter-name>JPivotController</filter-name>  
          23.     <url-pattern>/testpage.jsp</url-pattern>  
          24.   </filter-mapping>  
          復制下面的listener到我們的web.xml文件中(用于初始化一些資源)
          1. <listener>  
          2.     <listener-class>mondrian.web.taglib.Listener</listener-class>  
          3.   </listener>  
          4.   
          5.   <!– 資源初始化-->  
          6.   <listener>  
          7.     <listener-class>com.tonbeller.tbutils.res.ResourcesFactoryContextListener</listener-class>  
          8.   </listener>  
          Print  servlet,該servlet用于將數據生成Excel文件或pdf文件并返回給用戶,如果您需要用到該功能,則需要將其copy到您項目的web.xml文件中
          1. <servlet>  
          2.     <servlet-name>Print</servlet-name>  
          3.     <display-name>Print</display-name>  
          4.     <description>Default configuration created for servlet.</description>  
          5.     <servlet-class>com.tonbeller.jpivot.print.PrintServlet</servlet-class>  
          6.   </servlet>  
          7.  <servlet-mapping>  
          8.     <servlet-name>Print</servlet-name>  
          9.     <url-pattern>/Print</url-pattern>  
          10.   </servlet-mapping>  
          MDXQueryServlet用于接受并執行一個MDX查詢,然后將該查詢以Html表格的形式返回。其中的參數connectString用于指定連接到數據庫的字符串,例如使用jtds驅動連接到sql server 2000的字符串如下:

          Provider=mondrian;Jdbc=jdbc:jtds:sqlserver://localhost/Tezz;user=sa;password=123456;Catalog=/WEB-INF/queries/tezz.xml;JdbcDrivers=net.sourceforge.jtds.jdbc.Driver; 

          如果您需要用到該功能,則需要將其copy到您項目的web.xml文件中。

          1. <servlet>  
          2.     <servlet-name>MDXQueryServlet</servlet-name>  
          3.     <servlet-class>mondrian.web.servlet.MDXQueryServlet</servlet-class>  
          4.     <init-param>  
          5.       <param-name>connectString</param-name>  
          6.       <param-value>@mondrian.webapp.connectString@</param-value>  
          7.     </init-param>  
          8.   </servlet>  
          9.  <servlet-mapping>  
          10.     <servlet-name>MDXQueryServlet</servlet-name>  
          11.     <url-pattern>/mdxquery</url-pattern>  
          12.   </servlet-mapping>  
          DisplayChart 和GetChart 這兩個Servlet 用于生成圖表和將其顯示給最終用戶,如果您需要用到該功能,則需要將其copy到您項目的web.xml文件中。
          1. <!-- jfreechart provided servlet -->  
          2.   <servlet>  
          3.     <servlet-name>DisplayChart</servlet-name>  
          4.     <servlet-class>org.jfree.chart.servlet.DisplayChart</servlet-class>  
          5.   </servlet>  
          6.   <!-- jfreechart provided servlet -->  
          7.   <servlet>  
          8.     <servlet-name>GetChart</servlet-name>  
          9.     <display-name>GetChart</display-name>  
          10.     <description>Default configuration created for servlet.</description>  
          11.     <servlet-class>com.tonbeller.jpivot.chart.GetChart</servlet-class>  
          12.   </servlet>  
          13. <servlet-mapping>  
          14.     <servlet-name>DisplayChart</servlet-name>  
          15.     <url-pattern>/DisplayChart</url-pattern>  
          16.   </servlet-mapping>  
          17. <servlet-mapping>  
          18.     <servlet-name>GetChart</servlet-name>  
          19.     <url-pattern>/GetChart</url-pattern>  
          20.   </servlet-mapping>  
          它們用于向用戶生成和顯示如下所示的各種圖表:

          最后添加以下標簽庫到我們的web.xml項目中即可

          1. <taglib>  
          2.    <taglib-uri>http://www.tonbeller.com/wcf</taglib-uri>  
          3.    <taglib-location>/WEB-INF/wcf/wcf-tags.tld</taglib-location>  
          4.  </taglib>  
          5.   
          6.  <taglib>  
          7.    <taglib-uri>http://www.tonbeller.com/jpivot</taglib-uri>  
          8.    <taglib-location>/WEB-INF/jpivot/jpivot-tags.tld</taglib-location>  
          9.  </taglib>  
          到這里,您應該對mondrian在web.xml的配置有一定的了解,并可按需要添加相應的功能。

          接下來我們將要創建本例子所要用到的表格及數據。

          2.6 準備測試用表

          本例使用的表結構如下所示:


          Sale是事實表,它有兩個維:客戶(customer)維和由兩個表組成的產品(Product)維。

          表格的創建很簡單,您只需要將下面的sql語句導入數據庫即可

          2.6.1 使用以下sql語句創建表

          1. /**銷售表*/  
          2. create table Sale (  
          3.     saleId int not null,  
          4.     proId int null,  
          5.     cusId int null,   
          6.     unitPrice float null,    --單價  
          7.     number int null,     --數量  
          8.     constraint PK_SALE primary key (saleId)  
          9. )  
          10.     /**用戶表*/  
          11. create table Customer (  
          12.     cusId int not null,  
          13.     gender char(1) null,    --性別  
          14.     constraint PK_CUSTOMER primary key (cusId)  
          15. )  
          16. /**產品表*/  
          17. create table Product (  
          18.     proId int not null,  
          19.     proTypeId int null,  
          20.     proName varchar(32) null,  
          21.     constraint PK_PRODUCT primary key (proId)  
          22. )  
          23. /**產品類別表*/  
          24. create table ProductType (  
          25.     proTypeId int not null,  
          26.     proTypeName varchar(32) null,  
          27.     constraint PK_PRODUCTTYPE primary key (proTypeId)  
          28. )  

          2.6.2 使用以下sql語句導入數據

          1. insert into Customer(cusId,gender) values(1,'F')  
          2. insert into Customer(cusId,gender) values(2,'M')  
          3. insert into Customer(cusId,gender) values(3,'M')  
          4. insert into Customer(cusId,gender) values(4,'F')  
          5. insert into producttype(proTypeId,proTypeName) values(1,'電器')  
          6. insert into producttype(proTypeId,proTypeName) values(2,'數碼')  
          7. insert into producttype(proTypeId,proTypeName) values(3,'家具')  
          8. insert into product(proId,proTypeId,proName) values(1,1,'洗衣機')  
          9. insert into product(proId,proTypeId,proName) values(2,1,'電視機')  
          10. insert into product(proId,proTypeId,proName) values(3,2,'mp3')  
          11. insert into product(proId,proTypeId,proName) values(4,2,'mp4')  
          12. insert into product(proId,proTypeId,proName) values(5,2,'數碼相機')  
          13. insert into product(proId,proTypeId,proName) values(6,3,'椅子')  
          14. insert into product(proId,proTypeId,proName) values(7,3,'桌子')  
          15. insert into sale(saleId,proId,cusId,unitPrice,number) values(1,1,1,340.34,2)  
          16. insert into sale(saleId,proId,cusId,unitPrice,number) values(2,1,2,140.34,1)  
          17. insert into sale(saleId,proId,cusId,unitPrice,number) values(3,2,3,240.34,3)  
          18. insert into sale(saleId,proId,cusId,unitPrice,number) values(4,3,4,540.34,4)  
          19. insert into sale(saleId,proId,cusId,unitPrice,number) values(5,4,1,80.34,5)  
          20. insert into sale(saleId,proId,cusId,unitPrice,number) values(6,5,2,90.34,26)  
          21. insert into sale(saleId,proId,cusId,unitPrice,number) values(7,6,3,140.34,7)  
          22. insert into sale(saleId,proId,cusId,unitPrice,number) values(8,7,4,640.34,28)  
          23. insert into sale(saleId,proId,cusId,unitPrice,number) values(9,6,1,140.34,29)  
          24. insert into sale(saleId,proId,cusId,unitPrice,number) values(10,7,2,740.34,29)  
          25. insert into sale(saleId,proId,cusId,unitPrice,number) values(11,5,3,30.34,28)  
          26. insert into sale(saleId,proId,cusId,unitPrice,number) values(12,4,4,1240.34,72)  
          27. insert into sale(saleId,proId,cusId,unitPrice,number) values(13,3,1,314.34,27)  
          28. insert into sale(saleId,proId,cusId,unitPrice,number) values(14,3,2,45.34,27)  

          2.7 建立模式(schema)文件

          一個模式定義了一個多維數據庫. 它包含一個邏輯模型(logical model)、一組數據立方(consisting of cubes)、層次(hierarchies)、和成員(members), 并映射到物理模型(關系數據庫)上。

          簡單的說,配置一個模式就是配置一個關系數據結構到多維數據結構的映射。

          注:關于mondrian的模式及模式的配置,您可以通過閱讀mondrian的基本模式.pptx來了解。這里我們只對其進行了簡單介紹。

          2.7.1 創建模式文件:

          模式文件的創建很簡單。首先在WEB-INF下新建一個queries的文件夾,然后在該文件夾下創建一個名為tezz.xml的文件。再按下面的步驟將xml元素添加入即可。


          2.7.2 配置模式文件:

          2.7.2.1 添加數據立方Sales:


          2.7.2.2 添加數據立方Sales的維:


          添加產品維(因為產品維由兩個表連接而成,因此比客戶維復雜些):


          添加度量(共有三個度量:數量、平均單價和總銷售額):


          最后生成的tezz.xml文件內容如下:

          1. <?xml version="1.0" encoding="UTF-8"?>  
          2. <Schema name="tezz">  
          3. <Cube name="Sales">  
          4.     <!-- 事實表(fact table) -->  
          5.     <Table name="sale" />  
          6.     <!-- 客戶維 -->  
          7.     <Dimension name="客戶性別" foreignKey="cusId">  
          8.         <Hierarchy hasAll="true" allMemberName="所有性別" primaryKey="cusId">  
          9.             <Table name="Customer"></Table>  
          10.             <Level name="gender" column="gender"></Level>  
          11.         </Hierarchy>  
          12.     </Dimension>  
          13.     <!-- 產品類別維 -->  
          14.     <Dimension name="產品類別" foreignKey="proId">  
          15.         <Hierarchy hasAll="true" allMemberName="所有產品" primaryKey="proId" primaryKeyTable="product">  
          16.             <join leftKey="proTypeId" rightKey="proTypeId">  
          17.                 <Table name="product" />  
          18.                 <Table name="producttype"></Table>  
          19.             </join>  
          20.             <Level name="proTypeId" column="proTypeId"  
          21.                 nameColumn="proTypeName" uniqueMembers="true" table="producttype" />  
          22.             <Level name="proId" column="proId" nameColumn="proName"  
          23.                 uniqueMembers="true" table="product" />  
          24.         </Hierarchy>  
          25.     </Dimension>  
          26.     <Measure name="數量" column="number" aggregator="sum" datatype="Numeric" />  
          27.     <Measure name="總銷售額" aggregator="sum" formatString="¥#,##0.00">  
          28.         <!-- unitPrice*number所得值的列 -->  
          29.         <MeasureExpression>  
          30.             <SQL dialect="generic">(unitPrice*number)</SQL>  
          31.         </MeasureExpression>  
          32.     </Measure>  
          33.     <CalculatedMember name="平均單價" dimension="Measures">  
          34.         <Formula>[Measures].[總銷售額] / [Measures].[數量]</Formula>  
          35.         <CalculatedMemberProperty name="FORMAT_STRING" value="¥#,##0.00" />  
          36.     </CalculatedMember>  
          37. </Cube>  
          38. </Schema>  

          2.8 編寫MDX查詢語句

          在模式文件定義完成之后,我們就可以根據它來編寫相應MDX查詢語句了。

          本例所用的MDX語句如下:

          2.9 創建查詢文件

          現在我們將創建一個jsp文件,該jsp使用jpivot的mondrianQuery標簽來完成查詢。

          該文件最后將被testpage.jsp使用。

          在/WEB-INF/queries文件夾下面創建一名為tezz的jsp文件。該jsp包含如下內容:


          2.10 布署項目

          至此我們已經全部配置完成,文件結構如下:


          布署項目,啟動Tomcat,在瀏覽器上輸入http://localhost:8080/Tezz/testpage.jsp?query=tezz即可看到如下結果:


          注:testpage.jsp?query=tezz,這里的tezz即剛我們創建的用于查詢jsp文件名稱


          3.  testpage.jsp的流程

          testpage.jsp文件用于發出查詢及將結果轉換成html格式。它使用一組jsp標簽來完成這些復雜的工作。

          在本教程的最后一章里,我們對testpage.jsp的流程及用到的主要標簽進行簡單介紹。

          3.1 wcf:include標簽:


          3.2 jp:table標簽:

          <jp:table id="table01" query="#{query01}"/>

          jp:table根據query01中保存的結果(領域數據)準備顯示OLAP表格所需的數據(顯示數據)

          <wcf:render ref="table01" xslUri="/WEB-INF/jpivot/table/mdxtable.xsl"/>

          根據table01的結果,使用mdxtable.xsl中的配置,渲染出OLAP表格。

          3.3 其他jp、wcf標簽

          同樣,其他jp標簽,如<jp:chart id=“chart01“ ---/>等標簽準備待渲染的數據,再由相應的<wcf:render ref=“chart01” ---/>標簽將它們渲染成html格式。

          這樣,用戶將在瀏覽器上看到最終的結果。

          至此,一個完整的mondrian查詢結束。


          posted @ 2016-02-06 18:18 gdufo| 編輯 收藏

          導航

          統計

          常用鏈接

          留言簿(6)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          Hibernate

          友情鏈接

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 江西省| 易门县| 安多县| 平定县| 德昌县| 陇南市| 会宁县| 突泉县| 抚宁县| 武威市| 林州市| 泌阳县| 明星| 沙雅县| 石渠县| 建德市| 乌拉特后旗| 兴城市| 攀枝花市| 荆州市| 察雅县| 大石桥市| 蒲江县| 汽车| 绥化市| 京山县| 石渠县| 水富县| 礼泉县| 尉犁县| 黄大仙区| 汕尾市| 洪雅县| 乐业县| 南乐县| 桦川县| 彰化市| 九龙县| 江都市| 台中市| 安乡县|