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

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

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

    blog.Toby

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      130 隨筆 :: 2 文章 :: 150 評論 :: 0 Trackbacks
    多數 IT 組織都必須解決三個主要問題: 1 .幫助組織減少成本 2 .增加并且保持客戶 3 .加快業務效率。完成這些問題一般都需要實現對多個業務系統的數據和業務邏輯的無縫訪問,也就是說,要實施系統集成工程,以便聯結業務流程、實現數據的訪問與共享。

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

    1. 前言
    JpetStore 4.0
    ibatis 的最新示例程序。 ibatis 是開源的持久層產品,包含 SQL Maps 2.0 Data Access Objects 2.0 框架。 JpetStore 示例程序很好的展示了如何利用 ibatis 來開發一個典型的 J2EE web 應用程序。 JpetStore 有如下特點:

    • ibatis 數據層

    • POJO 業務層

    • POJO 領域類

    • Struts MVC

    • JSP 表示層

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

    • Struts 是目前 Java Web MVC 框架中不爭的王者。經過長達五年的發展, Struts 已經逐漸成長為一個穩定、成熟的框架,并且占有了 MVC 框架中最大的市場份額。但是 Struts 某些技術特性上已經落后于新興的 MVC 框架。面對 Spring MVC Webwork2 這些設計更精密,擴展性更強的框架, Struts 受到了前所未有的挑戰。但站在產品開發的角度而言, Struts 仍然是最穩妥的選擇。本文的原型例子 JpetStore 4.0 就是基于 Struts 開發的,但是不拘泥于 Struts 的傳統固定用法,例如只用了一個自定義 Action 類,并且在 form bean 類的定義上也是開創性的,令人耳目一新,稍后將具體剖析一下。

    • Spring Framework 實際上是 Expert One-on-One J2EE Design and Development 一書中所闡述的設計思想的具體實現。 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 ,它能將接口與實現分開,非常強大。目前 AOP 應用最成熟的還是在事務管理上。

    • ibatis 是一個功能強大實用的 SQL Map 工具,不同于其他 ORM 工具(如 hibernate ),它是將 SQL 語句映射成 Java 對象,而對于 ORM 工具,它的 SQL 語句是根據映射定義生成的。 ibatis SQL 開發的工作量和數據庫移植性上的讓步,為系統設計提供了更大的自由空間。有 ibatis 代碼生成的工具,可以根據 DDL 自動生成 ibatis 代碼,能減少很多工作量。

    2. JpetStore 簡述

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

    2.2. JpetStore 開發運行環境的建立
    1
    、開發環境

    • 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 建??蚣埽?/span> lomboz 插件需要,可以使用 runtime 版本。

    • lomboz 3.0 J2EE 插件,用來在 Eclipse 中開發 J2EE 應用程序

    • Spring IDE 1.0.3 Spring Bean 配置管理插件

    • xmlbuddy_2.0.10 :編輯 XML ,用免費版功能即可

    • tomcatPluginV3 tomcat 管理插件

    • Properties Editor :編輯 java 的屬性文件 , 并可以預覽以及自動存盤為 Unicode 格式。免去了手工或者 ANT 調用 native2ascii 的麻煩。

    3 、示例源程序

    • ibatis 示例程序 JpetStore 4.0 http://www.ibatis.com/jpetstore/jpetstore.html

    • 改造后的源程序( +spring )(源碼鏈接)

    2.3. 架構

    1 JpetStore 架構圖

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

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

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

    												
    														
    																?

    												
    														
    																 public String myActionMethod() {

    												
    														
    																
    																		?? //..work

    												
    														
    																
    																		?? return "success";

    												
    														
    																 }

    												
    														
    																
    																
    														
    														
    																

    方法的返回值直接就是字符串,對應的是 forward 的名稱,而不再是 ActionForward 對象,創建 ActionForward 對象的任務已經由 BeanAction 類代勞了。

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

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

    2 JpetStore 4.0 具體實現

    2.4. 代碼剖析
    下面就讓我們開始進一步分析 JpetStore4.0 的源代碼,為下面的改造鋪路。

    • BeanAction.java 是唯一一個 Struts action 類,位于 com.ibatis.struts 包下。正如上文所言,它是一個通用的控制類,利用反射機制,把控制轉移到 form bean 的某個方法來處理。詳細處理過程參考其源代碼,簡單明晰。

    ·???????? Form bean 類位于 com.ibatis.jpetstore.presentation 包下,命名規則為 ***Bean 。 Form bean 類全部繼承于 BaseBean 類,而 BaseBean 類實際繼承于 ActionForm ,因此, Form bean 類就是 Struts ActionForm , Form bean 類的屬性數據就由 struts 框架自動填充。而實際上, JpetStore4.0 擴展了 struts ActionForm 的應用: Form bean 類還具有行為,更像一個 BO, 其行為(方法)由 BeanAction 根據配置( struts-config.xml )的 URL 來調用。雖然如此,我們還是把 Form bean 類定位于表現層。

    Struts-config.xml 的配置里有 3 種映射方式,來告訴 BeanAction 把控制轉到哪個 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>

    												
    														
    																
    																		? 
    																
    														
    														
    																

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

    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>

    												
    														
    																
    																		? 
    																
    														
    														
    																

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

    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 上沒有任何方法被調用。如果存在 "name" 屬性,則 struts 把表單參數等數據填充到 form bean 對象后,把控制轉發到 "success" 。否則,如果 name 為空,則直接轉發控制到 "success" 。

    這就相當于 struts 內置的 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 包下,屬于業務層。這些類封裝了業務以及相應的事務控制。 Service 類由 form bean 類來調用。

    • com.ibatis.jpetstore.persistence.iface 包下的類是 DAO 接口,屬于業務層,其屏蔽了底層的數據庫操作,供具體的 Service 類來調用。 DaoConfig 類是工具類( DAO 工廠類), Service 類通過 DaoConfig 類來獲得相應的 DAO 接口,而不用關心底層的具體數據庫操作,實現了如圖 2 { 耦合 2} 的解耦。

    • com.ibatis.jpetstore.persistence.sqlmapdao 包下的類是對應 DAO 接口的具體實現,在 JpetStore4.0 中采用了 ibatis 來實現 ORM 。這些實現類繼承 BaseSqlMapDao 類,而 BaseSqlMapDao 類則繼承 ibatis DAO 框架中的 SqlMapDaoTemplate 類。 ibatis 的配置文件存放在 com.ibatis.jpetstore.persistence.sqlmapdao.sql 目錄下。這些類和配置文件位于數據層

    • Domain 類位于 com.ibatis.jpetstore.domain 包下,是普通的 javabean 。在這里用作數據傳輸對象( DTO ),貫穿視圖層、業務層和數據層,用于在不同層之間傳輸數據。

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

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

    1. 業務層和數據層用 Spring BeanFactory 機制管理。

    2. 業務層的事務由 spring aop 通過聲明來完成。

    3. 表現層( form bean )獲取業務類的方法改由自定義工廠類來實現(加載 spring 環境)。

    3. JPetStore 的改造

    3.1. 改造后的架構


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

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

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

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

    3.3. 表現層
    面分析到, struts spring 是在表現層銜接起來的,那么表現層就要做稍微的更改,即所需要的 service 類的對象創建上。以表現層的 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 類以同樣方式改造。這樣,表現層就完成了。關于表現層的其它部分如 JSP 等一概不動。也許您會說,沒有看出什么特別之處的好處???你還是額外實現了一個工廠類。別著急,帷幕剛剛開啟, spring 是在表現層引入,但您發沒發現:

    • presentation 類僅僅面向 service 類的接口編程,具體 "AccountService" 是哪個實現類, presentation 類不知道,是在 spring 的配置文件里配置。(本例中,為了最大限度的保持原來的代碼不作變化,沒有抽象出接口)。 Spring 鼓勵面向接口編程,因為是如此的方便和自然,當然您也可以不這么做。

    • CustomBeanFactory 這個工廠類為什么會如此簡單,因為其直接使用了 Spring BeanFactory 。 Spring 從其核心而言,是一個 DI 容器,其設計哲學是提供一種無侵入式的高擴展性的框架。為了實現這個目標, Spring 大量引入了 Java Reflection 機制,通過動態調用的方式避免硬編碼方式的約束,并在此基礎上建立了其核心組件 BeanFactory ,以此作為其依賴注入機制的實現基礎。 org.springframework.beans 包中包括了這些核心組件的實現類,核心中的核心為 BeanWrapper BeanFactory 類。

    3.4. 持久層
    在討論業務層之前,我們先看一下持久層,如下圖所示:


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

    1 、修改基類

    所有的 DAO 實現類都繼承于 BaseSqlMapDao 類。修改 BaseSqlMapDao 類如下:

    												
    														
    																?

    												
    														
    																public class BaseSqlMapDao extends SqlMapClientDaoSupport {

    												
    														
    																
    																		? protected static final int PAGE_SIZE = 4;

    												
    														
    																
    																		? protected SqlMapClientTemplate smcTemplate = this.getSqlMapClientTemplate();

    												
    														
    																
    																		? public BaseSqlMapDao() { 

    												
    														
    																
    																		???????? }

    												
    														
    																}

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

    2 、修改 DAO 實現類

    所有的 DAO 實現類還是繼承于 BaseSqlMapDao 類,實現相應的 DAO 接口,但其相應的 DAO 操作委托 SqlMapClientTemplate 來執行,以 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);

    												
    														
    																
    																		? }

    												
    														
    																
    																		? 
    																
    														
    														
    																

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

    3 、除去工廠類以及相應的配置文件

    除去 DaoConfig.java 這個 DAO 工廠類和相應的配置文件 dao.xml ,因為 DAO 的獲取現在要用 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. 我們首先創建一個數據源 dataSource ,在這里配置的是 hsqldb 數據庫。如果是 ORACLE 數據庫, driverClassName 的值是 "oracle.jdbc.driver.OracleDriver" URL 的值類似于 "jdbc:oracle:thin:@wugfMobile:1521:cdcf" 。數據源現在由 spring 來管理,那么現在我們就可以去掉 properties 目錄下 database.properties 這個配置文件了;還有不要忘記修改 sql-map-config.xml ,去掉 <properties resource="properties/database.properties"/> 對它的引用。

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

    3. TransactionManager 節點。定義了事務,使用的是 DataSourceTransactionManager 。

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

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

    3.5. 業務層
    業務層的位置以及相關類,如下圖所示:


    在這個例子中只有 3 個業務類,我們以 OrderService 類為例來改造,這個類是最復雜的,其中涉及了事務。

    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 ,其實現類是 com.ibatis.jpetstore.service.OrderService ,分別引用了 ItemDao , OrderDao , SequenceDao 。該 bean insert* 實現了事務管理 (AOP 方式 ) 。 TransactionProxyFactoryBean 自動創建一個事務 advisor , advisor 包括一個基于事務屬性的 pointcut, 因此只有事務性的方法被攔截。

    2 、業務類的修改

    OrderService 為例:

    												
    														
    																?

    												
    														
    																public class OrderService {

    												
    														
    																?

    												
    														
    																
    																		?? /* Private Fields */

    												
    														
    																
    																		? private ItemDao itemDao;

    												
    														
    																
    																		? private OrderDao orderDao;

    												
    														
    																
    																		? private SequenceDao sequenceDao;

    												
    														
    																?

    												
    														
    																
    																		? /* Constructors */

    												
    														
    																?

    												
    														
    																
    																		? public OrderService() {

    												
    														
    																
    																		? }

    												
    														
    																?

    												
    														
    																/**

    												
    														
    																 * @param itemDao 要設置的 itemDao。

    												
    														
    																 */

    												
    														
    																public final void setItemDao(ItemDao itemDao) {

    												
    														
    																
    																		???????? this.itemDao = itemDao;

    												
    														
    																}

    												
    														
    																/**

    												
    														
    																 * @param orderDao 要設置的 orderDao。

    												
    														
    																 */

    												
    														
    																public final void setOrderDao(OrderDao orderDao) {

    												
    														
    																
    																		???????? this.orderDao = orderDao;

    												
    														
    																}

    												
    														
    																/**

    												
    														
    																 * @param sequenceDao 要設置的 sequenceDao。

    												
    														
    																 */

    												
    														
    																public final void setSequenceDao(SequenceDao sequenceDao) {

    												
    														
    																
    																		???????? this.sequenceDao = sequenceDao;

    												
    														
    																}

    												
    														
    																//剩下的部分

    												
    														
    																……
    														
    														
    																.

    												
    														
    																}

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

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

    參考資料

    ??????作者Blog:http://blog.csdn.net/yanwp/

    posted on 2006-04-21 14:47 渠上月 閱讀(339) 評論(0)  編輯  收藏 所屬分類: java tips
    主站蜘蛛池模板: 78成人精品电影在线播放日韩精品电影一区亚洲 | 88av免费观看| 亚洲免费在线观看视频| 成年美女黄网站18禁免费| 国产成人无码免费视频97 | 国产精品四虎在线观看免费| 亚洲AV网站在线观看| 伊伊人成亚洲综合人网7777| 久久精品国产亚洲av麻豆色欲| 亚洲avav天堂av在线网爱情| 国产亚洲视频在线观看| 全黄大全大色全免费大片| 1000部禁片黄的免费看| 国产成人高清精品免费软件| 亚洲愉拍99热成人精品热久久| 亚洲欧洲高清有无| 精品国产亚洲第一区二区三区| 青柠影视在线观看免费高清| 久久久久久国产a免费观看黄色大片 | 精品成在人线AV无码免费看| 男女交性永久免费视频播放| 亚洲VA成无码人在线观看天堂| 亚洲乱码在线视频| 一级做a爱过程免费视| 日本免费xxxx色视频| 亚洲不卡无码av中文字幕| 蜜芽亚洲av无码精品色午夜| 久久亚洲欧美国产精品| 久久免费区一区二区三波多野| 女人18毛片a级毛片免费视频| 国产亚洲av片在线观看16女人 | 亚洲国产国产综合一区首页| 亚洲丁香婷婷综合久久| 一级特黄aa毛片免费观看| 日韩免费三级电影| 亚洲午夜久久久精品影院| 国产AV日韩A∨亚洲AV电影| 久久久久久曰本AV免费免费| 亚洲免费视频一区二区三区| 亚洲av无码电影网| 99视频在线观看免费|