<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    gdufo

     

    2015年3月19日

    Mondrian 使用教程

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

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

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

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

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


    1. Mondrian是什么?

    Mondrian是一個(gè)開源項(xiàng)目。一個(gè)用Java寫成的OLAP引擎。它用MDX語言實(shí)現(xiàn)查詢,從關(guān)系數(shù)據(jù)庫(RDBMS)中讀取數(shù)據(jù)。然后經(jīng)過Java API以多維的方式對(duì)結(jié)果進(jìn)行展示。

    Mondrian的使用方式同JDBC驅(qū)動(dòng)類似。可以非常方便的與現(xiàn)有的Web項(xiàng)目集成

    1.1 Mondrian的體系結(jié)構(gòu)(Architecture)

    Mondrian OLAP 系統(tǒng)由四個(gè)層組成; 從最終用戶到數(shù)據(jù)中心, 順序?yàn)? 
    1.1.1 表現(xiàn)層(the presentation layer)
    1.1.2 維度層(the dimensional layer)
    1.1.3 集合層(the star layer)
    1.1.4 存儲(chǔ)層(the storage layer)
    結(jié)構(gòu)圖如下:


    1.1.1 表現(xiàn)層(the presentation layer)

    表現(xiàn)層決定了最終用戶將在他們的顯示器上看到什么, 及他們?nèi)绾瓮到y(tǒng)產(chǎn)生交互。

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

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

    1.1.1.1 Jpivot表現(xiàn)層

    JPivot 是Mondrian的表現(xiàn)層TagLib,一直保持著良好的開發(fā)進(jìn)度。

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

    jpivot使用XML/ XSLT渲染OLAP報(bào)表:

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

    jpivot完全基于JSP+TagLib:

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

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


    jpivot其實(shí)是一個(gè)自定義jsp的標(biāo)簽庫。它基于XML/XSLT配置來生成相應(yīng)的html。所幸的是,我們并不需要了解太多關(guān)于這方面的內(nèi)容,我們只要掌握相應(yīng)jsp標(biāo)簽的使用即可。

    在本教程的實(shí)例中,我們將會(huì)對(duì)一些常用到的jpivot標(biāo)簽進(jìn)行講解。

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

    1.1.2 維度層(the dimensional layer)

    維度層用來解析、驗(yàn)證和執(zhí)行MDX查詢要求。

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

     為了提高效率,維度層把要求查詢的單元成批發(fā)送到集合層,查詢轉(zhuǎn)換器接受操作現(xiàn)有查詢的請(qǐng)求,而不是對(duì)每個(gè)請(qǐng)求都建立一個(gè)MDX 聲明。

    1.1.3 集合層(the star layer)

    集合層負(fù)責(zé)維護(hù)和創(chuàng)建集合緩存,一個(gè)集合是在內(nèi)存中緩存一組單元值, 這些單元值由一組維的值來確定。

    維度層對(duì)這些單元發(fā)出查詢請(qǐng)求,如果所查詢的單元值不在緩存中,則集合管理器(aggregation manager)會(huì)向存儲(chǔ)層發(fā)出查詢請(qǐng)求

    1.1.4 存儲(chǔ)層(the storage layer)

    存儲(chǔ)層是一個(gè)關(guān)系型數(shù)據(jù)庫(RDBMS)。它負(fù)責(zé)創(chuàng)建集合的單元數(shù)據(jù),和提供維表的成員。

    1.2 API

    Mondrian 為客戶端提供一個(gè)用于查詢的API

    因?yàn)榈侥壳盀橹?并沒有一個(gè)通用的用于OLAP查詢的API,因此Mondrian提供了它私有的API.

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

    下面的java片段展示了如何連接到Mondrian,然后執(zhí)行一個(gè)查詢,最后打印結(jié)果.

    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類似,一個(gè)Connection由DriverManager創(chuàng)建,Query 對(duì)象類似于JDBC 的Statement,它通過傳遞一個(gè)MDX語句來創(chuàng)建.Result對(duì)象類似于JDBC的ResultSet,只不過它里面保存的是多維數(shù)據(jù)

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

    通過上面的介紹,您應(yīng)該對(duì)mondrian的體系有一個(gè)基本的了解。

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


    2. 一個(gè)簡單的Mondrian例子

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

    2.1 準(zhǔn)備開發(fā)工具及環(huán)境

    本測試需要的環(huán)境:
    操作系統(tǒng):Windows 2000;
    Web服務(wù)器:tomcat6.0;
    關(guān)系數(shù)據(jù)庫:sql server 2000;
    開發(fā)工具:eclipse + myeclipse;
          JDBC驅(qū)動(dòng):jtds-1.2.2;

             您可以在http://tomcat.apache.org/上下載到tomcat的最新版本及幫助;
          您可以在http://www.myeclipseide.com/上下載到myeclipse的最新版本及相應(yīng)的eclipse開發(fā)平臺(tái)版本

    2.2 準(zhǔn)備Mondrian資源:

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


    2.3 創(chuàng)建項(xiàng)目

    啟動(dòng)eclipse。

    在eclipse中新創(chuàng)建一個(gè)web項(xiàng)目,名為Tezz。注意需要加入JSTL支持。

    具體步驟如下:

    2.3.1  打開新建web項(xiàng)目對(duì)話框



    一個(gè)新項(xiàng)目Tezz的文件結(jié)構(gòu)如下:


    2.4 添加必須的文件

    將下載的壓縮包進(jìn)行解壓。完成后,進(jìn)入文件夾可以看到如下目錄結(jié)構(gòu)。雙擊進(jìn)入lib文件夾。


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


    進(jìn)入解壓后的文件夾,選中jpivot、wcf二個(gè)文件夾及busy.jsp、error.jsp、testpage.jsp三個(gè)文件,我們需要將這些資源復(fù)制到我們測試項(xiàng)目的WebRoot文件夾中。按ctrl+C鍵復(fù)制。


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

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


    粘貼完成后的項(xiàng)目結(jié)構(gòu)如下


    注意:因?yàn)槲覀冞€未將所有資料復(fù)制到項(xiàng)目中,因此eclipse會(huì)顯示錯(cuò)誤圖標(biāo)

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


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

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


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

    2.5 配置web.xml

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


    過濾器(filter)

    復(fù)制如下所示的xml代碼到我們測試項(xiàng)目Tezz的web.xml文件中。

    作用:這個(gè)過濾器在訪問/testpage.jsp前被調(diào)用。它被設(shè)計(jì)成jpivot的前端控制器,用于判斷并將用戶的請(qǐng)求發(fā)送到某個(gè)頁面。

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

    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>如果這是一個(gè)新的會(huì)話,則轉(zhuǎn)到此頁面</description>  
    8.     </init-param>  
    9.     <init-param>  
    10.       <param-name>errorJSP</param-name>  
    11.       <param-value>/error.jsp</param-value>  
    12.       <description>出錯(cuò)時(shí)顯示的頁面</description>  
    13.     </init-param>  
    14.     <init-param>  
    15.       <param-name>busyJSP</param-name>  
    16.       <param-value>/busy.jsp</param-value>  
    17.       <description>這個(gè)頁面用于當(dāng)用戶點(diǎn)擊一個(gè)查詢時(shí),在這個(gè)查詢還未將結(jié)果還回給用戶時(shí)所顯示的界面</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>  
    復(fù)制下面的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用于將數(shù)據(jù)生成Excel文件或pdf文件并返回給用戶,如果您需要用到該功能,則需要將其copy到您項(xiàng)目的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用于接受并執(zhí)行一個(gè)MDX查詢,然后將該查詢以Html表格的形式返回。其中的參數(shù)connectString用于指定連接到數(shù)據(jù)庫的字符串,例如使用jtds驅(qū)動(dòng)連接到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到您項(xiàng)目的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 這兩個(gè)Servlet 用于生成圖表和將其顯示給最終用戶,如果您需要用到該功能,則需要將其copy到您項(xiàng)目的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>  
    它們用于向用戶生成和顯示如下所示的各種圖表:

    最后添加以下標(biāo)簽庫到我們的web.xml項(xiàng)目中即可

    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>  
    到這里,您應(yīng)該對(duì)mondrian在web.xml的配置有一定的了解,并可按需要添加相應(yīng)的功能。

    接下來我們將要?jiǎng)?chuàng)建本例子所要用到的表格及數(shù)據(jù)。

    2.6 準(zhǔn)備測試用表

    本例使用的表結(jié)構(gòu)如下所示:


    Sale是事實(shí)表,它有兩個(gè)維:客戶(customer)維和由兩個(gè)表組成的產(chǎn)品(Product)維。

    表格的創(chuàng)建很簡單,您只需要將下面的sql語句導(dǎo)入數(shù)據(jù)庫即可

    2.6.1 使用以下sql語句創(chuàng)建表

    1. /**銷售表*/  
    2. create table Sale (  
    3.     saleId int not null,  
    4.     proId int null,  
    5.     cusId int null,   
    6.     unitPrice float null,    --單價(jià)  
    7.     number int null,     --數(shù)量  
    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. /**產(chǎn)品表*/  
    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. /**產(chǎn)品類別表*/  
    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語句導(dǎo)入數(shù)據(jù)

    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,'數(shù)碼')  
    7. insert into producttype(proTypeId,proTypeName) values(3,'家具')  
    8. insert into product(proId,proTypeId,proName) values(1,1,'洗衣機(jī)')  
    9. insert into product(proId,proTypeId,proName) values(2,1,'電視機(jī)')  
    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,'數(shù)碼相機(jī)')  
    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)文件

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

    簡單的說,配置一個(gè)模式就是配置一個(gè)關(guān)系數(shù)據(jù)結(jié)構(gòu)到多維數(shù)據(jù)結(jié)構(gòu)的映射。

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

    2.7.1 創(chuàng)建模式文件:

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


    2.7.2 配置模式文件:

    2.7.2.1 添加數(shù)據(jù)立方Sales:


    2.7.2.2 添加數(shù)據(jù)立方Sales的維:


    添加產(chǎn)品維(因?yàn)楫a(chǎn)品維由兩個(gè)表連接而成,因此比客戶維復(fù)雜些):


    添加度量(共有三個(gè)度量:數(shù)量、平均單價(jià)和總銷售額):


    最后生成的tezz.xml文件內(nèi)容如下:

    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <Schema name="tezz">  
    3. <Cube name="Sales">  
    4.     <!-- 事實(shí)表(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.     <!-- 產(chǎn)品類別維 -->  
    14.     <Dimension name="產(chǎn)品類別" foreignKey="proId">  
    15.         <Hierarchy hasAll="true" allMemberName="所有產(chǎn)品" 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="數(shù)量" 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="平均單價(jià)" dimension="Measures">  
    34.         <Formula>[Measures].[總銷售額] / [Measures].[數(shù)量]</Formula>  
    35.         <CalculatedMemberProperty name="FORMAT_STRING" value="¥#,##0.00" />  
    36.     </CalculatedMember>  
    37. </Cube>  
    38. </Schema>  

    2.8 編寫MDX查詢語句

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

    本例所用的MDX語句如下:

    2.9 創(chuàng)建查詢文件

    現(xiàn)在我們將創(chuàng)建一個(gè)jsp文件,該jsp使用jpivot的mondrianQuery標(biāo)簽來完成查詢。

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

    在/WEB-INF/queries文件夾下面創(chuàng)建一名為tezz的jsp文件。該jsp包含如下內(nèi)容:


    2.10 布署項(xiàng)目

    至此我們已經(jīng)全部配置完成,文件結(jié)構(gòu)如下:


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


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


    3.  testpage.jsp的流程

    testpage.jsp文件用于發(fā)出查詢及將結(jié)果轉(zhuǎn)換成html格式。它使用一組jsp標(biāo)簽來完成這些復(fù)雜的工作。

    在本教程的最后一章里,我們對(duì)testpage.jsp的流程及用到的主要標(biāo)簽進(jìn)行簡單介紹。

    3.1 wcf:include標(biāo)簽:


    3.2 jp:table標(biāo)簽:

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

    jp:table根據(jù)query01中保存的結(jié)果(領(lǐng)域數(shù)據(jù))準(zhǔn)備顯示OLAP表格所需的數(shù)據(jù)(顯示數(shù)據(jù))

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

    根據(jù)table01的結(jié)果,使用mdxtable.xsl中的配置,渲染出OLAP表格。

    3.3 其他jp、wcf標(biāo)簽

    同樣,其他jp標(biāo)簽,如<jp:chart id=“chart01“ ---/>等標(biāo)簽準(zhǔn)備待渲染的數(shù)據(jù),再由相應(yīng)的<wcf:render ref=“chart01” ---/>標(biāo)簽將它們渲染成html格式。

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

    至此,一個(gè)完整的mondrian查詢結(jié)束。


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

    Java調(diào)用MQ隊(duì)列

    http://blog.csdn.net/ozwarld/article/details/7735915

    IBM MQ 6.0中設(shè)置兩個(gè)隊(duì)列,(遠(yuǎn)程隊(duì)列、通道之類都不設(shè)置)。

    隊(duì)列管理器是XIR_QM_1502

    隊(duì)列名稱是ESBREQ

    IP地址是10.23.117.134(遠(yuǎn)程的一臺(tái)電腦,跟我的電腦不在一個(gè)局域網(wǎng)內(nèi))

    端口1414

    CCSID 1208


    MQ配置可以參考這個(gè),有配圖http://wenku.baidu.com/view/06d108d0360cba1aa811daa3.html

    程序如下,發(fā)送線程兩個(gè),接收線程一個(gè)。接收完畢后就結(jié)束。


    1. /* 
    2.  * 創(chuàng)建日期 2012-7-10 
    3.  * 
    4.  * TODO 要更改此生成的文件的模板,請(qǐng)轉(zhuǎn)至 
    5.  * 窗口 - 首選項(xiàng) - Java - 代碼樣式 - 代碼模板 
    6.  */  
    7. package yerasel;  
    8.   
    9. /** 
    10.  * @author Fenglb E-mail:56553655@163.com 
    11.  * @version 創(chuàng)建時(shí)間:2009-4-30 下午04:13:38 類說明 
    12.  */  
    13.   
    14. import java.io.IOException;  
    15. import com.ibm.mq.MQC;  
    16. import com.ibm.mq.MQEnvironment;  
    17. import com.ibm.mq.MQException;  
    18. import com.ibm.mq.MQGetMessageOptions;  
    19. import com.ibm.mq.MQMessage;  
    20. import com.ibm.mq.MQPutMessageOptions;  
    21. import com.ibm.mq.MQQueue;  
    22. import com.ibm.mq.MQQueueManager;  
    23.   
    24. interface SomeConstants {  
    25.     String qManager = "XIR_QM_1502";//"XIR_QM"; //QueueManager name  
    26.     String qName = "ESBREQ";// Queue Name  
    27.     String strIP = "10.23.117.134";//"10.24.28.139";//"10.24.28.102";  
    28.     int iPort = 1502;//1414;  
    29.     String strChl = "SYSTEM.DEF.SVRCONN";// Server-Connection Channel  
    30.     int iCCSID = 1208;  
    31. }  
    32.   
    33. class Sender implements Runnable, SomeConstants {  
    34.     public void run() {  
    35.         sendMessage();  
    36.     }  
    37.   
    38.     public void sendMessage() {  
    39.   
    40.         String name = Thread.currentThread().getName();  
    41.         System.out.println("進(jìn)入線程" + name);  
    42.   
    43.         MQQueueManager qMgr = null;  
    44.         // configure connection parameters  
    45.   
    46.         MQEnvironment.hostname = strIP;  
    47.         // Server name or IP  
    48.         MQEnvironment.port = iPort;  
    49.         MQEnvironment.channel = strChl;  
    50.         MQEnvironment.CCSID = iCCSID;  
    51.   
    52.         // java程序連接mq的方式有兩種,一是客戶機(jī)方式,一是綁定方式,  
    53.         // 默認(rèn)是客戶機(jī)方式,當(dāng)mq部署在本地的時(shí)候,就需要用綁定方式  
    54.         // 本機(jī)IP是10.24.28.139連接10.23.117.134的時(shí)候不需要下句  
    55.         //MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY,  
    56.         //MQC.TRANSPORT_MQSERIES_BINDINGS);  
    57.   
    58.         // Create a connection to the QueueManager  
    59.         System.out.println(name + " Connecting to queue manager: " + qManager);  
    60.         try {  
    61.             qMgr = new MQQueueManager(qManager);  
    62.             // Set up the options on the queue we wish to open  
    63.             int openOptions = MQC.MQMT_REQUEST | MQC.MQPMO_NEW_MSG_ID  
    64.                     | MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING  
    65.                     | MQC.MQOO_INPUT_AS_Q_DEF;  
    66.             // Now specify the queue that we wish to open and the open options  
    67.             System.out.println(name + " Accessing queue: " + qName);  
    68.             MQQueue queue = qMgr.accessQueue(qName, openOptions);  
    69.             // Define a simple WebSphere MQ Message ...  
    70.   
    71.             // Specify the default put message options  
    72.             MQPutMessageOptions pmo = new MQPutMessageOptions();  
    73.   
    74.             // Put the message to the queue  
    75.             System.out.println(name + " Sending a message...");  
    76.   
    77.             MQMessage msg = new MQMessage();  
    78.             msg.messageId = "MSGID".getBytes();  
    79.             msg.messageType = MQC.MQMT_REQUEST;  
    80.             msg.replyToQueueName = "ESBREQ";  
    81.   
    82.             // 在此測試一下 mq 的傳輸次列  
    83.             for (int j = 1; j < 5; j++) {  
    84.                 msg.messageSequenceNumber = j;  
    85.                 // write some text in UTF8 format  
    86.                 try {  
    87.                     String str = "Salemetsizbe Yerasel";  
    88.                     str = str + " " + j;  
    89.                     msg.writeUTF(str);  
    90.                     queue.put(msg, pmo);  
    91.                     msg.clearMessage();  
    92.                     System.out.println(name + " putting the message... " + j);  
    93.                 } catch (MQException mqe) {  
    94.                     mqe.printStackTrace();  
    95.                     break;  
    96.                 } catch (IOException e1) {  
    97.                     e1.printStackTrace();  
    98.                 }  
    99.             }  
    100.             qMgr.commit();  
    101.             System.out.println(name + " Done!");  
    102.             System.out.println("==========");  
    103.             System.out.println("");  
    104.         } catch (MQException e) {  
    105.             e.printStackTrace();  
    106.         }  
    107.     }  
    108. }  
    109.   
    110. class Receiver implements Runnable, SomeConstants {  
    111.   
    112.     public void run() {  
    113.         recvMessage();  
    114.     }  
    115.   
    116.     public void recvMessage() {  
    117.   
    118.         String name = Thread.currentThread().getName();  
    119.           
    120.         try {  
    121.             Thread.sleep(1000);  
    122.             MQQueueManager qMgr = null;  
    123.   
    124.               
    125.             System.out.println("進(jìn)入線程" + name);  
    126.   
    127.             System.out.println(name + " Connecting to queue manager: "  
    128.                     + qManager);  
    129.             qMgr = new MQQueueManager(qManager);  
    130.             // 設(shè)置將要連接的隊(duì)列屬性  
    131.             // Note. The MQC interface defines all the constants used by the  
    132.             // WebSphere MQ Java programming interface  
    133.             // (except for completion code constants and error code constants).  
    134.             // MQOO_INPUT_AS_Q_DEF:Open the queue to get messages using the  
    135.             // queue-defined default.  
    136.             // MQOO_OUTPUT:Open the queue to put messages.  
    137.             int openOptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT  
    138.                     | MQC.MQOO_INQUIRE;  
    139.   
    140.             // Now get the message back again. First define a WebSphere MQ  
    141.             // message to receive the data  
    142.             MQMessage rcvMessage = new MQMessage();  
    143.   
    144.             // Specify default get message options  
    145.             MQGetMessageOptions gmo = new MQGetMessageOptions();  
    146.             gmo.options = gmo.options + MQC.MQGMO_SYNCPOINT;// Get messages  
    147.                                                             // under sync point  
    148.                                                             // control(在同步點(diǎn)控制下獲取消息)  
    149.             gmo.options = gmo.options + MQC.MQGMO_WAIT; // Wait if no messages  
    150.                                                         // on the  
    151.                                                         // Queue(如果在隊(duì)列上沒有消息則等待)  
    152.             gmo.options = gmo.options + MQC.MQGMO_FAIL_IF_QUIESCING;// Fail if  
    153.                                                                     // Qeue  
    154.                                                                     // Manager  
    155.                                                                     // Quiescing(如果隊(duì)列管理器停頓則失敗)  
    156.             gmo.waitInterval = 1000; // Sets the time limit for the  
    157.                                         // wait.(設(shè)置等待的毫秒時(shí)間限制)  
    158.   
    159.             System.out.println(name + " Accessing queue: " + qName);  
    160.             MQQueue queue = qMgr.accessQueue(qName, openOptions);  
    161.             int depth = 0;  
    162.   
    163.             // Get the message off the queue.  
    164.             System.out.println("... " + name + " getting the message back again");  
    165.             for (;;) {  
    166.                 try {  
    167.                     queue.get(rcvMessage, gmo);  
    168.                     System.out.println(" ID: "  
    169.                             + (new String(rcvMessage.messageId)).trim()  
    170.                             + " Num: " + rcvMessage.messageSequenceNumber  
    171.                             + " Type: " + rcvMessage.messageType + " Flag: "  
    172.                             + rcvMessage.messageFlags);  
    173.                     // And display the message text...  
    174.                     String msgText = rcvMessage.readUTF();  
    175.                     System.out.println("The message is: " + msgText);  
    176.                     rcvMessage.clearMessage();  
    177.   
    178.                     // Break if no MSG left in queue  
    179.                     depth = queue.getCurrentDepth();  
    180.                     if (depth == 0)  
    181.                         break;  
    182.   
    183.                 } catch (MQException mqe) {  
    184.                     mqe.printStackTrace();  
    185.                     break;  
    186.                     // null;  
    187.                 } catch (IOException e) {  
    188.                     e.printStackTrace();  
    189.                 }  
    190.             }  
    191.             // Close the queue  
    192.             System.out.println(name + " Closing the queue");  
    193.             queue.close();  
    194.             // Disconnect from the QueueManager  
    195.             System.out.println(name + " Disconnecting from the Queue Manager");  
    196.             qMgr.disconnect();  
    197.             System.out.println(name + " Done!");  
    198.             System.out.println("==========");  
    199.             System.out.println("");  
    200.         } catch (MQException ex) {  
    201.             System.out  
    202.                     .println("A WebSphere MQ Error occured : Completion Code "  
    203.                             + ex.completionCode + " Reason Code "  
    204.                             + ex.reasonCode + ex.getMessage());  
    205.         } catch (InterruptedException e1) {  
    206.             e1.printStackTrace();  
    207.         }  
    208.     }  
    209. }  
    210.   
    211. public class MQTest {  
    212.   
    213.     public static void main(String args[]) {  
    214.   
    215.         /* 
    216.          * MQTest first = new MQTest(); first.sendMessage(); 
    217.          * first.recvMessage(); 
    218.          */  
    219.         Sender sender = new Sender();  
    220.         Thread senderThread = new Thread(sender);  
    221.         senderThread.start();  
    222.         senderThread.setName("Sender");  
    223.           
    224.         Thread senderThread2 = new Thread(sender);  
    225.         senderThread2.start();  
    226.         senderThread2.setName("Sender2");  
    227.           
    228.         Receiver recv = new Receiver();  
    229.         Thread recvThread = new Thread(recv);  
    230.         recvThread.start();  
    231.         recvThread.setName("Receiver");  
    232.   
    233.         // Receiver recv = new Receiver();  
    234.         // new Thread(recv).start();  
    235.   
    236.     }  
    237.   
    238. }  


    運(yùn)行結(jié)果如下:

    進(jìn)入線程Sender2
    進(jìn)入線程Sender
    Sender2 Connecting to queue manager: XIR_QM_1502
    Sender Connecting to queue manager: XIR_QM_1502
    Sender2 Accessing queue: ESBREQ
    Sender2 Sending a message...
    Sender Accessing queue: ESBREQ
    Sender Sending a message...
    Sender2 putting the message... 1
    Sender putting the message... 1
    Sender2 putting the message... 2
    Sender putting the message... 2
    Sender2 putting the message... 3
    Sender putting the message... 3
    Sender2 putting the message... 4
    Sender putting the message... 4
    Sender2 Done!
    ==========


    Sender Done!
    ==========


    進(jìn)入線程Receiver
    Receiver Connecting to queue manager: XIR_QM_1502
    Receiver Accessing queue: ESBREQ
    ... Receiver getting the message back again
     ID: MSGID Num: 1 Type: 1 Flag: 0
    The message is: Salemetsizbe Yerasel 1
     ID: MSGID Num: 1 Type: 1 Flag: 0
    The message is: Salemetsizbe Yerasel 1
     ID: MSGID Num: 1 Type: 1 Flag: 0
    The message is: Salemetsizbe Yerasel 2
     ID: MSGID Num: 1 Type: 1 Flag: 0
    The message is: Salemetsizbe Yerasel 2
     ID: MSGID Num: 1 Type: 1 Flag: 0
    The message is: Salemetsizbe Yerasel 3
     ID: MSGID Num: 1 Type: 1 Flag: 0
    The message is: Salemetsizbe Yerasel 3
     ID: MSGID Num: 1 Type: 1 Flag: 0
    The message is: Salemetsizbe Yerasel 4
     ID: MSGID Num: 1 Type: 1 Flag: 0
    The message is: Salemetsizbe Yerasel 4
    Receiver Closing the queue
    Receiver Disconnecting from the Queue Manager
    Receiver Done!

    posted @ 2015-08-26 12:07 gdufo| 編輯 收藏

    Linux 下 安裝 PHP 的 PDO_MYSQL 擴(kuò)展

    Linux 下 安裝 PHP 的 PDO_MYSQL 擴(kuò)展

    2013 年 3 月 11 日 – 09:41 | 2,420 views | Favorite收藏
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

    PDO_MYSQL以下操作都在Linux 系統(tǒng)下操作

    1、下載 文件 或者 進(jìn)入 在PHP源碼包中進(jìn)入ext/pdo_mysql

    http://pecl.php.net/get/PDO_MYSQL-1.0.2.tgz

    2、解壓文件
    tar zxvf PDO_MYSQL-1.0.2.tgz

    3、配置和編譯文件
    #cd PDO_MYSQL-1.0.2
    #/usr/local/php5/bin/phpize
    #./configure –with-php-config=/usr/local/php5/bin/php-config –with-pdo-mysql=/usr/local/mysql
    #make
    #make install

    注: 我的PHP安裝在 : /usr/local/php5/ mysql 安裝在 : /usr/local/mysql 編譯的時(shí)候注意你自己的安裝目錄在哪里
    3、安裝到PHP配置下

    把這個(gè)記住,然后打開 php.ini文件,
    并添加一行

    extension=pdo_mysql.so

    并將上面編譯產(chǎn)生的so復(fù)制到 php.ini文件中extension_dir指定的目錄中

    重新啟動(dòng)!

    posted @ 2015-03-19 10:30 gdufo| 編輯 收藏

    Linux下php安裝mcrypt擴(kuò)展

    說明:

    操作系統(tǒng):CentOS 5.x 64位

    已安裝php版本:php-5.4.4

    已安裝php路徑:/usr/local/php

    實(shí)現(xiàn)目的:

    在不影響網(wǎng)站訪問的情況下,重新編譯php,增加對(duì)mcrypt擴(kuò)展的支持

    具體操作:

    一、下載軟件包

    1、下載php版本要與系統(tǒng)安裝的一致

    http://museum.php.net/php5/php-5.4.4.tar.gz

    2、下載libmcrypt安裝mcrypt需要此軟件包

    http://nchc.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz

    3、下載mhash安裝mcrypt需要此軟件包

    https://acelnmp.googlecode.com/files/mhash-0.9.9.9.tar.gz

    4、下載mcrypt

    https://lcmp.googlecode.com/files/mcrypt-2.6.8.tar.gz

    以上軟件包下載之后,上傳到/usr/local/src目錄

    二、安裝軟件包

    1、安裝libmcrypt

    cd /usr/local/src  #進(jìn)入軟件包存放目錄

    tar zxvf libmcrypt-2.5.8.tar.gz  #解壓

    cd libmcrypt-2.5.8  #進(jìn)入安裝目錄

    ./configure  #配置

    make  #編譯

    make install  #安裝

    2、安裝mhash

    cd /usr/local/src

    tar zxvf mhash-0.9.9.9.tar.gz

    cd mhash-0.9.9.9

    ./configure

    make

    make install

    3、安裝mcrypt

    cd /usr/local/src

    tar zxvf mcrypt-2.6.8.tar.gz

    cd mcrypt-2.6.8

    ln -s   /usr/local/bin/libmcrypt_config   /usr/bin/libmcrypt_config  #添加軟連接

    export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH  #添加環(huán)境變量

    ./configure

    make

    make install

    三、重新編譯php

    1、查看系統(tǒng)之前安裝的php編譯參數(shù)

    系統(tǒng)運(yùn)維  www.osyunwei.com  溫馨提醒:qihang01原創(chuàng)內(nèi)容 版權(quán)所有,轉(zhuǎn)載請(qǐng)注明出處及原文鏈接

    /usr/local/php/bin/php -i |grep configure  #查看php編譯參數(shù),記錄下編譯參數(shù),后面會(huì)用到

    2、安裝php

    cd /usr/local/src

    tar zxvf php-5.4.4.tar.gz

    cd php-5.4.4

    './configure' '--prefix=/usr/local/php' '--enable-mbstring=all' '--with-config-file-path=/usr/local/php/etc' '--with-zlib' '--with-mysql=/usr/local/mysql-5.1.38/' '--with-gd' '--with-mysqli=/usr/local/mysql-5.1.38/bin/mysql_config' '--with-jpeg-dir=/usr' '--with-png-dir=/usr' '--enable-fpm' '--enable-soap' '--with-freetype-dir=/usr/lib64' '--with-iconv=/usr/local' '--with-curl' '--with-mcrypt'

    #在之前的編譯參數(shù)后面增加'--with-mcrypt' 回車

    make  #編譯

    make install  #安裝

    /usr/local/src/php-5.4.4/sapi/fpm/init.d.php-fpm  reload  #重新加載php-fpm

    四、測試mcrypt擴(kuò)展是否已安裝成功

    在網(wǎng)站目錄下新建一個(gè)info.php測試頁面,寫上下面代碼,保存

    <?php

    phpinfo();

    ?>

    在瀏覽器中打開info.php 會(huì)看到如下的信息

    說明mcrypt擴(kuò)展已經(jīng)安裝成功

    至此,Linux下php安裝mcrypt擴(kuò)展完成。

    posted @ 2015-03-19 10:20 gdufo| 編輯 收藏

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(6)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    收藏夾

    Hibernate

    友情鏈接

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲精品乱码久久久久蜜桃| 亚洲国产成人片在线观看无码| 91精品免费国产高清在线| 久久国产精品2020免费m3u8| 91人人区免费区人人| 蜜桃视频在线观看免费网址入口| 日本免费高清一本视频| 亚洲午夜久久久影院| 亚洲精品视频在线观看免费| 色噜噜噜噜亚洲第一| 国产一二三四区乱码免费| 国产精品视频免费| 精品亚洲456在线播放| AAAAA级少妇高潮大片免费看| 一二三四视频在线观看中文版免费| 亚洲色偷拍区另类无码专区| 亚洲成aⅴ人在线观看| 国产在线国偷精品免费看| 国产精品白浆在线观看免费 | 花蝴蝶免费视频在线观看高清版| 无码国产精品一区二区免费式影视 | 中国一级特黄高清免费的大片中国一级黄色片 | 国产成人无码区免费A∨视频网站| 一本久久a久久精品亚洲| 亚洲一区二区三区国产精华液| 国产福利电影一区二区三区,免费久久久久久久精 | 亚洲高清在线视频| 亚洲视频在线观看| 国国内清清草原免费视频99| 亚洲欧美中文日韩视频| AV无码免费永久在线观看| 亚洲欧美日韩国产精品一区| 亚洲日本va午夜中文字幕久久| 曰批全过程免费视频在线观看无码| 亚洲精品在线免费观看视频| 成人无码区免费视频观看| selaoban在线视频免费精品| 少妇中文字幕乱码亚洲影视| 久久免费美女视频| 亚洲中文字幕久久精品无码APP| 99久久免费观看|