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

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

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

    Dict.CN 在線詞典, 英語學(xué)習(xí), 在線翻譯

    都市淘沙者

    荔枝FM Everyone can be host

    統(tǒng)計

    留言簿(23)

    積分與排名

    優(yōu)秀學(xué)習(xí)網(wǎng)站

    友情連接

    閱讀排行榜

    評論排行榜

    基于struts+spring+ibatis的輕量級J2EE開發(fā)

    吳高峰 (shuwgf@21cn.com)常德卷煙廠信息技術(shù)部

    2005 年 2 月 01 日

    大多數(shù)IT 組織都必須解決三個主要問題:1.幫助組織減少成本 2.增加并且保持客戶 3.加快業(yè)務(wù)效率。完成這些問題一般都需要實現(xiàn)對多個業(yè)務(wù)系統(tǒng)的數(shù)據(jù)和業(yè)務(wù)邏輯的無縫訪問,也就是說,要實施系統(tǒng)集成工程,以便聯(lián)結(jié)業(yè)務(wù)流程、實現(xiàn)數(shù)據(jù)的訪問與共享。

    JpetStore 4.0是ibatis的最新示例程序,基于Struts MVC框架(注:非傳統(tǒng)Struts開發(fā)模式),以ibatis作為持久化層。該示例程序設(shè)計優(yōu)雅,層次清晰,可以學(xué)習(xí)以及作為一個高效率的編程模型參考。本文是在其基礎(chǔ)上,采用Spring對其中間層(業(yè)務(wù)層)進(jìn)行改造。使開發(fā)量進(jìn)一步減少,同時又擁有了Spring的一些好處…

    1. 前言

    JpetStore 4.0是ibatis的最新示例程序。ibatis是開源的持久層產(chǎn)品,包含SQL Maps 2.0 和 Data Access Objects 2.0 框架。JpetStore示例程序很好的展示了如何利用ibatis來開發(fā)一個典型的J2EE web應(yīng)用程序。JpetStore有如下特點:

    • ibatis數(shù)據(jù)層
    • POJO業(yè)務(wù)層
    • POJO領(lǐng)域類
    • Struts MVC
    • JSP 表示層

    以下是本文用到的關(guān)鍵技術(shù)介紹,本文假設(shè)您已經(jīng)對Struts,SpringFramewok,ibatis有一定的了解,如果不是,請首先查閱附錄中的參考資料。

    • Struts 是目前Java Web MVC框架中不爭的王者。經(jīng)過長達(dá)五年的發(fā)展,Struts已經(jīng)逐漸成長為一個穩(wěn)定、成熟的框架,并且占有了MVC框架中最大的市場份額。但是Struts某些技術(shù)特性上已經(jīng)落后于新興的MVC框架。面對Spring MVC、Webwork2 這些設(shè)計更精密,擴(kuò)展性更強(qiáng)的框架,Struts受到了前所未有的挑戰(zhàn)。但站在產(chǎn)品開發(fā)的角度而言,Struts仍然是最穩(wěn)妥的選擇。本文的原型例子JpetStore 4.0就是基于Struts開發(fā)的,但是不拘泥于Struts的傳統(tǒng)固定用法,例如只用了一個自定義Action類,并且在form bean類的定義上也是開創(chuàng)性的,令人耳目一新,稍后將具體剖析一下。
    • Spring Framework 實際上是Expert One-on-One J2EE Design and Development 一書中所闡述的設(shè)計思想的具體實現(xiàn)。Spring Framework的功能非常多。包含AOP、ORM、DAO、Context、Web、MVC等幾個部分組成。Web、MVC暫不用考慮,JpetStore 4.0用的是更成熟的Struts和JSP;DAO由于目前Hibernate、JDO、ibatis的流行,也不考慮,JpetStore 4.0用的就是ibatis。因此最需要用的是AOP、ORM、Context。Context中,最重要的是Beanfactory,它能將接口與實現(xiàn)分開,非常強(qiáng)大。目前AOP應(yīng)用最成熟的還是在事務(wù)管理上。
    • ibatis 是一個功能強(qiáng)大實用的SQL Map工具,不同于其他ORM工具(如hibernate),它是將SQL語句映射成Java對象,而對于ORM工具,它的SQL語句是根據(jù)映射定義生成的。ibatis 以SQL開發(fā)的工作量和數(shù)據(jù)庫移植性上的讓步,為系統(tǒng)設(shè)計提供了更大的自由空間。有ibatis代碼生成的工具,可以根據(jù)DDL自動生成ibatis代碼,能減少很多工作量。




    回頁首


    2. JpetStore簡述

    2.1. 背景

    最初是Sun公司的J2EE petstore,其最主要目的是用于學(xué)習(xí)J2EE,但是其缺點也很明顯,就是過度設(shè)計了。接著Oracle用J2EE petstore來比較各應(yīng)用服務(wù)器的性能。微軟推出了基于.Net平臺的 Pet shop,用于競爭J2EE petstore。而JpetStore則是經(jīng)過改良的基于struts的輕便框架J2EE web應(yīng)用程序,相比來說,JpetStore設(shè)計和架構(gòu)更優(yōu)良,各層定義清晰,使用了很多最佳實踐和模式,避免了很多"反模式",如使用存儲過程,在java代碼中嵌入SQL語句,把HTML存儲在數(shù)據(jù)庫中等等。最新版本是JpetStore 4.0。

    2.2. JpetStore開發(fā)運行環(huán)境的建立

    1、開發(fā)環(huán)境

    • Java SDK 1.4.2
    • Apache Tomcat 4.1.31
    • Eclipse-SDK-3.0.1-win32
    • HSQLDB 1.7.2

    2、Eclipse插件

    • EMF SDK 2.0.1:Eclipse建模框架,lomboz插件需要,可以使用runtime版本。
    • lomboz 3.0:J2EE插件,用來在Eclipse中開發(fā)J2EE應(yīng)用程序
    • Spring IDE 1.0.3:Spring Bean配置管理插件
    • xmlbuddy_2.0.10:編輯XML,用免費版功能即可
    • tomcatPluginV3:tomcat管理插件
    • Properties Editor:編輯java的屬性文件,并可以預(yù)覽以及自動存盤為Unicode格式。免去了手工或者ANT調(diào)用native2ascii的麻煩。

    3、示例源程序

    • ibatis示例程序JpetStore 4.0 http://www.ibatis.com/jpetstore/jpetstore.html
    • 改造后的源程序(+spring)(源碼鏈接)

    2.3. 架構(gòu)



    圖1 JpetStore架構(gòu)圖
    圖1 JpetStore架構(gòu)圖

    圖1 是JPetStore架構(gòu)圖,更詳細(xì)的內(nèi)容請參見JPetStore的白皮書。參照這個架構(gòu)圖,讓我們稍微剖析一下源代碼,得出JpetStore 4.0的具體實現(xiàn)圖(見圖2),思路一下子就豁然開朗了。前言中提到的非傳統(tǒng)的struts開發(fā)模式,關(guān)鍵就在struts Action類和form bean類上。

    struts Action類只有一個:BeanAction。沒錯,確實是一個!與傳統(tǒng)的struts編程方式很不同。再仔細(xì)研究BeanAction類,發(fā)現(xiàn)它其實是一個通用類,利用反射原理,根據(jù)URL來決定調(diào)用formbean的哪個方法。BeanAction大大簡化了struts的編程模式,降低了對struts的依賴(與struts以及WEB容器有關(guān)的幾個類都放在com.ibatis.struts包下,其它的類都可以直接復(fù)用)。利用這種模式,我們會很容易的把它移植到新的框架如JSF,spring。

    這樣重心就轉(zhuǎn)移到form bean上了,它已經(jīng)不是普通意義上的form bean了。查看源代碼,可以看到它不僅僅有數(shù)據(jù)和校驗/重置方法,而且已經(jīng)具有了行為,從這個意義上來說,它更像一個BO(Business Object)。這就是前文講到的,BeanAction類利用反射原理,根據(jù)URL來決定調(diào)用form bean的哪個方法(行為)。form bean的這些方法的簽名很簡單,例如:



     public String myActionMethod() {
       //..work
       return "success";
     }
     

    方法的返回值直接就是字符串,對應(yīng)的是forward的名稱,而不再是ActionForward對象,創(chuàng)建ActionForward對象的任務(wù)已經(jīng)由BeanAction類代勞了。

    另外,程序還提供了ActionContext工具類,該工具類封裝了request 、response、form parameters、request attributes、session attributes和 application attributes中的數(shù)據(jù)存取操作,簡單而線程安全,form bean類使用該工具類可以進(jìn)一步從表現(xiàn)層框架解耦。

    在這里需要特別指出的是,BeanAction類是對struts擴(kuò)展的一個有益嘗試,雖然提供了非常好的應(yīng)用開發(fā)模式,但是它還非常新,一直在發(fā)展中。



    圖2 JpetStore 4.0具體實現(xiàn)
    圖2 JpetStore 4.0具體實現(xiàn)

    2.4. 代碼剖析

    下面就讓我們開始進(jìn)一步分析JpetStore4.0的源代碼,為下面的改造鋪路。

    • BeanAction.java是唯一一個Struts action類,位于com.ibatis.struts包下。正如上文所言,它是一個通用的控制類,利用反射機(jī)制,把控制轉(zhuǎn)移到form bean的某個方法來處理。詳細(xì)處理過程參考其源代碼,簡單明晰。
    • Form bean類位于com.ibatis.jpetstore.presentation包下,命名規(guī)則為***Bean。Form bean類全部繼承于BaseBean類,而BaseBean類實際繼承于ActionForm,因此,F(xiàn)orm bean類就是Struts的 ActionForm,F(xiàn)orm bean類的屬性數(shù)據(jù)就由struts框架自動填充。而實際上,JpetStore4.0擴(kuò)展了struts中ActionForm的應(yīng)用: Form bean類還具有行為,更像一個BO,其行為(方法)由BeanAction根據(jù)配置(struts-config.xml)的URL來調(diào)用。雖然如此,我們還是把Form bean類定位于表現(xiàn)層。

      Struts-config.xml的配置里有3種映射方式,來告訴BeanAction把控制轉(zhuǎn)到哪個form bean對象的哪個方法來處理。

      以這個請求連接為例http://localhost/jpetstore4/shop/viewOrder.do

      1. URL Pattern

          <action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
          name="orderBean" scope="session"
          validate="false">
          <forward name="success" path="/order/ViewOrder.jsp"/>
        </action>
        

      此種方式表示,控制將被轉(zhuǎn)發(fā)到"orderBean"這個form bean對象 的"viewOrder"方法(行為)來處理。方法名取"path"參數(shù)的以"/"分隔的最后一部分。

      2. Method Parameter

          <action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
          name="orderBean" parameter="viewOrder" scope="session"
          validate="false">
          <forward name="success" path="/order/ViewOrder.jsp"/>
        </action>
        

      此種方式表示,控制將被轉(zhuǎn)發(fā)到"orderBean"這個form bean對象的"viewOrder"方法(行為)來處理。配置中的"parameter"參數(shù)表示form bean類上的方法。"parameter"參數(shù)優(yōu)先于"path"參數(shù)。

      3. No Method call

          <action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
          name="orderBean" parameter="*" scope="session"
          validate="false">
          <forward name="success" path="/order/ViewOrder.jsp"/>
        </action>
        

      此種方式表示,form bean上沒有任何方法被調(diào)用。如果存在"name"屬性,則struts把表單參數(shù)等數(shù)據(jù)填充到form bean對象后,把控制轉(zhuǎn)發(fā)到"success"。否則,如果name為空,則直接轉(zhuǎn)發(fā)控制到"success"。

      這就相當(dāng)于struts內(nèi)置的org.apache.struts.actions.ForwardAction的功能

       <action path="/shop/viewOrder" type="org.apache.struts.actions.ForwardAction"
          parameter="/order/ViewOrder.jsp " scope="session" validate="false">
       </action>
       

    • Service類位于com.ibatis.jpetstore.service包下,屬于業(yè)務(wù)層。這些類封裝了業(yè)務(wù)以及相應(yīng)的事務(wù)控制。Service類由form bean類來調(diào)用。
    • com.ibatis.jpetstore.persistence.iface包下的類是DAO接口,屬于業(yè)務(wù)層,其屏蔽了底層的數(shù)據(jù)庫操作,供具體的Service類來調(diào)用。DaoConfig類是工具類(DAO工廠類),Service類通過DaoConfig類來獲得相應(yīng)的DAO接口,而不用關(guān)心底層的具體數(shù)據(jù)庫操作,實現(xiàn)了如圖2中{耦合2}的解耦。
    • com.ibatis.jpetstore.persistence.sqlmapdao包下的類是對應(yīng)DAO接口的具體實現(xiàn),在JpetStore4.0中采用了ibatis來實現(xiàn)ORM。這些實現(xiàn)類繼承BaseSqlMapDao類,而BaseSqlMapDao類則繼承ibatis DAO 框架中的SqlMapDaoTemplate類。ibatis的配置文件存放在com.ibatis.jpetstore.persistence.sqlmapdao.sql目錄下。這些類和配置文件位于數(shù)據(jù)層
    • Domain類位于com.ibatis.jpetstore.domain包下,是普通的javabean。在這里用作數(shù)據(jù)傳輸對象(DTO),貫穿視圖層、業(yè)務(wù)層和數(shù)據(jù)層,用于在不同層之間傳輸數(shù)據(jù)。

    剩下的部分就比較簡單了,請看具體的源代碼,非常清晰。

    2.5. 需要改造的地方

    JpetStore4.0的關(guān)鍵就在struts Action類和form bean類上,這也是其精華之一(雖然該實現(xiàn)方式是試驗性,待擴(kuò)充和驗證),在此次改造中我們要保留下來,即控制層一點不變,表現(xiàn)層獲取相應(yīng)業(yè)務(wù)類的方式變了(要加載spring環(huán)境),其它保持不變。要特別關(guān)注的改動是業(yè)務(wù)層和持久層,幸運的是JpetStore4.0設(shè)計非常好,需要改動的地方非常少,而且由模式可循,如下:

    1. 業(yè)務(wù)層和數(shù)據(jù)層用Spring BeanFactory機(jī)制管理。

    2. 業(yè)務(wù)層的事務(wù)由spring 的aop通過聲明來完成。

    3. 表現(xiàn)層(form bean)獲取業(yè)務(wù)類的方法改由自定義工廠類來實現(xiàn)(加載spring環(huán)境)。





    回頁首


    3. JPetStore的改造

    3.1. 改造后的架構(gòu)




    其中紅色部分是要增加的部分,藍(lán)色部分是要修改的部分。下面就讓我們逐一剖析。

    3.2. Spring Context的加載

    為了在Struts中加載Spring Context,一般會在struts-config.xml的最后添加如下部分:



    <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
    <set-property property="contextConfigLocation"
    value="/WEB-INF/applicationContext.xml" />
    </plug-in>
    

    Spring在設(shè)計時就充分考慮到了與Struts的協(xié)同工作,通過內(nèi)置的Struts Plug-in在兩者之間提供了良好的結(jié)合點。但是,因為在這里我們一點也不改動JPetStore的控制層(這是JpetStore4.0的精華之一),所以本文不準(zhǔn)備采用此方式來加載ApplicationContext。我們利用的是spring framework 的BeanFactory機(jī)制,采用自定義的工具類(bean工廠類)來加載spring的配置文件,從中可以看出Spring有多靈活,它提供了各種不同的方式來使用其不同的部分/層次,您只需要用你想用的,不需要的部分可以不用。

    具體的來說,就是在com.ibatis.spring包下創(chuàng)建CustomBeanFactory類,spring的配置文件applicationContext.xml也放在這個目錄下。以下就是該類的全部代碼,很簡單:



    public final class CustomBeanFactory {
    	static XmlBeanFactory factory = null;
    	static {
    		Resource is = new
    InputStreamResource( CustomBeanFactory.class.getResourceAsStream("applicationContext.xml"));
    		factory = new XmlBeanFactory(is);			
    	}
    	public static Object getBean(String beanName){
    		return factory.getBean(beanName);
    	}
    }
    

    實際上就是封裝了Spring 的XMLBeanFactory而已,并且Spring的配置文件只需要加載一次,以后就可以直接用CustomBeanFactory.getBean("someBean")來獲得需要的對象了(例如someBean),而不需要知道具體的類。CustomBeanFactory類用于{耦合1}的解耦。

    CustomBeanFactory類在本文中只用于表現(xiàn)層的form bean對象獲得service類的對象,因為我們沒有把form bean對象配置在applicationContext.xml中。但是,為什么不把表現(xiàn)層的form bean類也配置起來呢,這樣就用不著這CustomBeanFactory個類了,Spring會幫助我們創(chuàng)建需要的一切?問題的答案就在于form bean類是struts的ActionForm類!如果大家熟悉struts,就會知道ActionForm類是struts自動創(chuàng)建的:在一次請求中,struts判斷,如果ActionForm實例不存在,就創(chuàng)建一個ActionForm對象,把客戶提交的表單數(shù)據(jù)保存到ActionForm對象中。因此formbean類的對象就不能由spring來創(chuàng)建,但是service類以及數(shù)據(jù)層的DAO類可以,所以只有他們在spring中配置。

    所以,很自然的,我們就創(chuàng)建了CustomBeanFactory類,在表現(xiàn)層來銜接struts和spring。就這么簡單,實現(xiàn)了另一種方式的{耦合一}的解耦。

    3.3. 表現(xiàn)層

    面分析到,struts和spring是在表現(xiàn)層銜接起來的,那么表現(xiàn)層就要做稍微的更改,即所需要的service類的對象創(chuàng)建上。以表現(xiàn)層的AccountBean類為例:

    原來的源代碼如下



        private static final AccountService accountService = AccountService.getInstance();
      private static final CatalogService catalogService = CatalogService.getInstance();
      

    改造后的源代碼如下



      private static final AccountService accountService = (AccountService)CustomBeanFactory.getBean("AccountService");
      private static final CatalogService catalogService = (CatalogService)CustomBeanFactory.getBean("CatalogService");
    

    其他的幾個presentation類以同樣方式改造。這樣,表現(xiàn)層就完成了。關(guān)于表現(xiàn)層的其它部分如JSP等一概不動。也許您會說,沒有看出什么特別之處的好處啊?你還是額外實現(xiàn)了一個工廠類。別著急,帷幕剛剛開啟,spring是在表現(xiàn)層引入,但您發(fā)沒發(fā)現(xiàn):

    • presentation類僅僅面向service類的接口編程,具體"AccountService"是哪個實現(xiàn)類,presentation類不知道,是在spring的配置文件里配置。(本例中,為了最大限度的保持原來的代碼不作變化,沒有抽象出接口)。Spring鼓勵面向接口編程,因為是如此的方便和自然,當(dāng)然您也可以不這么做。
    • CustomBeanFactory這個工廠類為什么會如此簡單,因為其直接使用了Spring的BeanFactory。Spring從其核心而言,是一個DI容器,其設(shè)計哲學(xué)是提供一種無侵入式的高擴(kuò)展性的框架。為了實現(xiàn)這個目標(biāo),Spring 大量引入了Java 的Reflection機(jī)制,通過動態(tài)調(diào)用的方式避免硬編碼方式的約束,并在此基礎(chǔ)上建立了其核心組件BeanFactory,以此作為其依賴注入機(jī)制的實現(xiàn)基礎(chǔ)。org.springframework.beans包中包括了這些核心組件的實現(xiàn)類,核心中的核心為BeanWrapper和BeanFactory類。

    3.4. 持久層

    在討論業(yè)務(wù)層之前,我們先看一下持久層,如下圖所示:




    在上文中,我們把iface包下的DAO接口歸為業(yè)務(wù)層,在這里不需要做修改。ibatis的sql配置文件也不需要改。要改的是DAO實現(xiàn)類,并在spring的配置文件中配置起來。

    1、修改基類

    所有的DAO實現(xiàn)類都繼承于BaseSqlMapDao類。修改BaseSqlMapDao類如下:



    public class BaseSqlMapDao extends SqlMapClientDaoSupport {
      protected static final int PAGE_SIZE = 4;
      protected SqlMapClientTemplate smcTemplate = this.getSqlMapClientTemplate();
      public BaseSqlMapDao() { 
    	}
    }
    

    使BaseSqlMapDao類改為繼承于Spring提供的SqlMapClientDaoSupport類,并定義了一個保護(hù)屬性smcTemplate,其類型為SqlMapClientTemplate。關(guān)于SqlMapClientTemplate類的詳細(xì)說明請參照附錄中的"Spring中文參考手冊"

    2、修改DAO實現(xiàn)類

    所有的DAO實現(xiàn)類還是繼承于BaseSqlMapDao類,實現(xiàn)相應(yīng)的DAO接口,但其相應(yīng)的DAO操作委托SqlMapClientTemplate來執(zhí)行,以AccountSqlMapDao類為例,部分代碼如下:



        public List getUsernameList() {
        return smcTemplate.queryForList("getUsernameList", null);
      }
      public Account getAccount(String username, String password) {
        Account account = new Account();
        account.setUsername(username);
        account.setPassword(password);
        return (Account) smcTemplate.queryForObject("getAccountByUsernameAndPassword", account);
      }
      public void insertAccount(Account account) {
      	smcTemplate.update("insertAccount", account);
      	smcTemplate.update("insertProfile", account);
      	smcTemplate.update("insertSignon", account);
      }
      

    就這么簡單,所有函數(shù)的簽名都是一樣的,只需要查找替換就可以了!

    3、除去工廠類以及相應(yīng)的配置文件

    除去DaoConfig.java這個DAO工廠類和相應(yīng)的配置文件dao.xml,因為DAO的獲取現(xiàn)在要用spring來管理。

    4、DAO在Spring中的配置(applicationContext.xml)



        <bean id="dataSource" 
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName">
                <value>org.hsqldb.jdbcDriver</value>
            </property>
            <property name="url">
                <value>jdbc:hsqldb:hsql://localhost/xdb</value>
            </property>
            <property name="username">
                <value>sa</value>
            </property>
            <property name="password">
                <value></value>
            </property>
        </bean>    
        <!-- ibatis sqlMapClient config -->
        <bean id="sqlMapClient" 
            class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
            <property name="configLocation">
                <value> 
                    classpath:com\ibatis\jpetstore\persistence\sqlmapdao\sql\sql-map-config.xml
                </value>
            </property>
            <property name="dataSource">
                <ref bean="dataSource"/>
            </property>    
        </bean>
        <!-- Transactions -->
        <bean id="TransactionManager" 
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource">
                <ref bean="dataSource"/>
            </property>
        </bean>
        <!-- persistence layer -->
        <bean id="AccountDao" 
            class="com.ibatis.jpetstore.persistence.sqlmapdao.AccountSqlMapDao">
            <property name="sqlMapClient">
                <ref local="sqlMapClient"/>
            </property>
        </bean>
        

    具體的語法請參照附錄中的"Spring中文參考手冊"。在這里只簡單解釋一下:

    1. 我們首先創(chuàng)建一個數(shù)據(jù)源dataSource,在這里配置的是hsqldb數(shù)據(jù)庫。如果是ORACLE數(shù)據(jù)庫,driverClassName的值是"oracle.jdbc.driver.OracleDriver",URL的值類似于"jdbc:oracle:thin:@wugfMobile:1521:cdcf"。數(shù)據(jù)源現(xiàn)在由spring來管理,那么現(xiàn)在我們就可以去掉properties目錄下database.properties這個配置文件了;還有不要忘記修改sql-map-config.xml,去掉<properties resource="properties/database.properties"/>對它的引用。

    2. sqlMapClient節(jié)點。這個是針對ibatis SqlMap的SqlMapClientFactoryBean配置。實際上配置了一個sqlMapClient的創(chuàng)建工廠類。configLocation屬性配置了ibatis映射文件的名稱。dataSource屬性指向了使用的數(shù)據(jù)源,這樣所有使用sqlMapClient的DAO都默認(rèn)使用了該數(shù)據(jù)源,除非在DAO的配置中另外顯式指定。

    3. TransactionManager節(jié)點。定義了事務(wù),使用的是DataSourceTransactionManager。

    4. 下面就可以定義DAO節(jié)點了,如AccountDao,它的實現(xiàn)類是com.ibatis.jpetstore.persistence.sqlmapdao.AccountSqlMapDao,使用的SQL配置從sqlMapClient中讀取,數(shù)據(jù)庫連接沒有特別列出,那么就是默認(rèn)使用sqlMapClient配置的數(shù)據(jù)源datasource。

    這樣,我們就把持久層改造完了,其他的DAO配置類似于AccountDao。怎么樣?簡單吧。這次有接口了:) AccountDao接口->AccountSqlMapDao實現(xiàn)。

    3.5. 業(yè)務(wù)層

    業(yè)務(wù)層的位置以及相關(guān)類,如下圖所示:




    在這個例子中只有3個業(yè)務(wù)類,我們以O(shè)rderService類為例來改造,這個類是最復(fù)雜的,其中涉及了事務(wù)。

    1、在ApplicationContext配置文件中增加bean的配置:



        <bean id="OrderService" 
            class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
            <property name="transactionManager">
                <ref local="TransactionManager"></ref>
            </property>
            <property name="target">
                <bean class="com.ibatis.jpetstore.service.OrderService">
                    <property name="itemDao">
                        <ref bean="ItemDao"/>
                    </property>
                    <property name="orderDao">
                        <ref bean="OrderDao"/>
                    </property>
                    <property name="sequenceDao">
                        <ref bean="SequenceDao"/>
                    </property>
                </bean>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="insert*">PROPAGATION_REQUIRED</prop>
                </props>
            </property>
        </bean>
        

    定義了一個OrderService,還是很容易懂的。為了簡單起見,使用了嵌套bean,其實現(xiàn)類是com.ibatis.jpetstore.service.OrderService,分別引用了ItemDao,OrderDao,SequenceDao。該bean的insert*實現(xiàn)了事務(wù)管理(AOP方式)。TransactionProxyFactoryBean自動創(chuàng)建一個事務(wù)advisor, 該advisor包括一個基于事務(wù)屬性的pointcut,因此只有事務(wù)性的方法被攔截。

    2、業(yè)務(wù)類的修改

    以O(shè)rderService為例:



    public class OrderService {
       /* Private Fields */
      private ItemDao itemDao;
      private OrderDao orderDao;
      private SequenceDao sequenceDao;
      /* Constructors */
      public OrderService() {
      }
    /**
     * @param itemDao 要設(shè)置的 itemDao。
     */
    public final void setItemDao(ItemDao itemDao) {
    	this.itemDao = itemDao;
    }
    /**
     * @param orderDao 要設(shè)置的 orderDao。
     */
    public final void setOrderDao(OrderDao orderDao) {
    	this.orderDao = orderDao;
    }
    /**
     * @param sequenceDao 要設(shè)置的 sequenceDao。
     */
    public final void setSequenceDao(SequenceDao sequenceDao) {
    	this.sequenceDao = sequenceDao;
    }
    //剩下的部分
    …….
    }
    

    紅色部分為修改部分。Spring采用的是Type2的設(shè)置依賴注入,所以我們只需要定義屬性和相應(yīng)的設(shè)值函數(shù)就可以了,ItemDao,OrderDao,SequenceDao的值由spring在運行期間注入。構(gòu)造函數(shù)就可以為空了,另外也不需要自己編寫代碼處理事務(wù)了(事務(wù)在配置中聲明),daoManager.startTransaction();等與事務(wù)相關(guān)的語句也可以去掉了。和原來的代碼比較一下,是不是處理精簡了很多!可以更關(guān)注業(yè)務(wù)的實現(xiàn)。





    回頁首


    4. 結(jié)束語

    ibatis是一個功能強(qiáng)大實用的SQL Map工具,可以直接控制SQL,為系統(tǒng)設(shè)計提供了更大的自由空間。其提供的最新示例程序JpetStore 4.0,設(shè)計優(yōu)雅,應(yīng)用了迄今為止很多最佳實踐和設(shè)計模式,非常適于學(xué)習(xí)以及在此基礎(chǔ)上創(chuàng)建輕量級的J2EE WEB應(yīng)用程序。JpetStore 4.0是基于struts的,本文在此基礎(chǔ)上,最大程度保持了原有設(shè)計的精華以及最小的代碼改動量,在業(yè)務(wù)層和持久化層引入了Spring。在您閱讀了本文以及改造后的源代碼后,會深切的感受到Spring帶來的種種好處:自然的面向接口的編程,業(yè)務(wù)對象的依賴注入,一致的數(shù)據(jù)存取框架和聲明式的事務(wù)處理,統(tǒng)一的配置文件…更重要的是Spring既是全面的又是模塊化的,Spring有分層的體系結(jié)構(gòu),這意味著您能選擇僅僅使用它任何一個獨立的部分,就像本文,而它的架構(gòu)又是內(nèi)部一致。



    參考資料



    關(guān)于作者

    吳高峰,原一直在中興通訊從事運營支撐產(chǎn)品的研發(fā)工作,對J2EE以及各種開源項目感興趣。現(xiàn)在常德卷煙廠信息技術(shù)部從事EAI的建設(shè)。聯(lián)系方式:shuwgf@21cn.com


    posted on 2007-02-02 19:28 都市淘沙者 閱讀(238) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 四虎成人精品国产永久免费无码| 亚洲综合在线视频| 春暖花开亚洲性无区一区二区| 最新中文字幕电影免费观看| 亚洲一区在线视频观看| 无人在线直播免费观看| 麻豆狠色伊人亚洲综合网站| 最近的免费中文字幕视频| 亚洲精品乱码久久久久久V| 日韩激情淫片免费看| 韩国亚洲伊人久久综合影院| 免费永久在线观看黄网站| 成在线人直播免费视频| 精品亚洲一区二区| 亚洲免费在线视频观看| 亚洲中文无码av永久| 免费网站看v片在线香蕉| 女bbbbxxxx另类亚洲| 激情97综合亚洲色婷婷五| 国产一级婬片A视频免费观看| 亚洲av永久无码精品漫画| 4hu四虎最新免费地址| jzzijzzij在线观看亚洲熟妇| 亚洲国产精品第一区二区三区| CAOPORN国产精品免费视频| 亚洲国产成人私人影院| 亚洲中文无码永久免费| 国产亚洲精品国产福利在线观看| 老司机亚洲精品影视www| 最近2019中文字幕免费大全5| 亚洲男人天堂2018av| 久久精品国产精品亚洲下载| 91精品免费观看| 国产成人精品久久亚洲高清不卡 | 国产高清免费视频| 亚洲av中文无码字幕色不卡| 国产亚洲精品美女久久久| 日韩版码免费福利视频| 国产JIZZ中国JIZZ免费看| 亚洲一区中文字幕在线电影网| 亚洲av午夜精品一区二区三区 |