JpetStore 4.0
是
ibatis
的最新示例程序,基于
Struts MVC
框架(注:非傳統(tǒng)
Struts
開(kāi)發(fā)模式),以
ibatis
作為持久化層。該示例程序設(shè)計(jì)優(yōu)雅,層次清晰,可以學(xué)習(xí)以及作為一個(gè)高效率的編程模型參考。本文是在其基礎(chǔ)上,采用
Spring
對(duì)其中間層(業(yè)務(wù)層)進(jìn)行改造。使開(kāi)發(fā)量進(jìn)一步減少,同時(shí)又擁有了
Spring
的一些好處…
1.
前言
JpetStore 4.0
是
ibatis
的最新示例程序。
ibatis
是開(kāi)源的持久層產(chǎn)品,包含
SQL Maps 2.0
和
Data Access Objects 2.0
框架。
JpetStore
示例程序很好的展示了如何利用
ibatis
來(lái)開(kāi)發(fā)一個(gè)典型的
J2EE web
應(yīng)用程序。
JpetStore
有如下特點(diǎn):
-
ibatis
數(shù)據(jù)層
-
POJO
業(yè)務(wù)層
-
POJO
領(lǐng)域類(lèi)
- Struts MVC
-
JSP
表示層
以下是本文用到的關(guān)鍵技術(shù)介紹,本文假設(shè)您已經(jīng)對(duì)
Struts
,
SpringFramewok
,
ibatis
有一定的了解,如果不是,請(qǐng)首先查閱附錄中的參考資料。
-
Struts
是目前
Java Web MVC
框架中不爭(zhēng)的王者。經(jīng)過(guò)長(zhǎng)達(dá)五年的發(fā)展,
Struts
已經(jīng)逐漸成長(zhǎng)為一個(gè)穩(wěn)定、成熟的框架,并且占有了
MVC
框架中最大的市場(chǎng)份額。但是
Struts
某些技術(shù)特性上已經(jīng)落后于新興的
MVC
框架。面對(duì)
Spring MVC
、
Webwork2
這些設(shè)計(jì)更精密,擴(kuò)展性更強(qiáng)的框架,
Struts
受到了前所未有的挑戰(zhàn)。但站在產(chǎn)品開(kāi)發(fā)的角度而言,
Struts
仍然是最穩(wěn)妥的選擇。本文的原型例子
JpetStore 4.0
就是基于
Struts
開(kāi)發(fā)的,但是不拘泥于
Struts
的傳統(tǒng)固定用法,例如只用了一個(gè)自定義
Action
類(lèi),并且在
form bean
類(lèi)的定義上也是開(kāi)創(chuàng)性的,令人耳目一新,稍后將具體剖析一下。
-
Spring Framework
實(shí)際上是
Expert One-on-One J2EE Design and Development
一書(shū)中所闡述的設(shè)計(jì)思想的具體實(shí)現(xiàn)。
Spring Framework
的功能非常多。包含
AOP
、
ORM
、
DAO
、
Context
、
Web
、
MVC
等幾個(gè)部分組成。
Web
、
MVC
暫不用考慮,
JpetStore 4.0
用的是更成熟的
Struts
和
JSP
;
DAO
由于目前
Hibernate
、
JDO
、
ibatis
的流行,也不考慮,
JpetStore 4.0
用的就是
ibatis
。因此最需要用的是
AOP
、
ORM
、
Context
。
Context
中,最重要的是
Beanfactory
,它能將接口與實(shí)現(xiàn)分開(kāi),非常強(qiáng)大。目前
AOP
應(yīng)用最成熟的還是在事務(wù)管理上。
-
ibatis
是一個(gè)功能強(qiáng)大實(shí)用的
SQL Map
工具,不同于其他
ORM
工具(如
hibernate
),它是將
SQL
語(yǔ)句映射成
Java
對(duì)象,而對(duì)于
ORM
工具,它的
SQL
語(yǔ)句是根據(jù)映射定義生成的。
ibatis
以
SQL
開(kāi)發(fā)的工作量和數(shù)據(jù)庫(kù)移植性上的讓步,為系統(tǒng)設(shè)計(jì)提供了更大的自由空間。有
ibatis
代碼生成的工具,可以根據(jù)
DDL
自動(dòng)生成
ibatis
代碼,能減少很多工作量。
2. JpetStore
簡(jiǎn)述
2.1.
背景
最初是
Sun
公司的
J2EE petstore
,其最主要目的是用于學(xué)習(xí)
J2EE
,但是其缺點(diǎn)也很明顯,就是過(guò)度設(shè)計(jì)了。接著
Oracle
用
J2EE petstore
來(lái)比較各應(yīng)用服務(wù)器的性能。微軟推出了基于
.Net
平臺(tái)的
Pet shop
,用于競(jìng)爭(zhēng)
J2EE petstore
。而
JpetStore
則是經(jīng)過(guò)改良的基于
struts
的輕便框架
J2EE web
應(yīng)用程序,相比來(lái)說(shuō),
JpetStore
設(shè)計(jì)和架構(gòu)更優(yōu)良,各層定義清晰,使用了很多最佳實(shí)踐和模式,避免了很多
"
反模式
"
,如使用存儲(chǔ)過(guò)程,在
java
代碼中嵌入
SQL
語(yǔ)句,把
HTML
存儲(chǔ)在數(shù)據(jù)庫(kù)中等等。最新版本是
JpetStore 4.0
。
2.2. JpetStore
開(kāi)發(fā)運(yùn)行環(huán)境的建立
1
、開(kāi)發(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
插件,用來(lái)在
Eclipse
中開(kāi)發(fā)
J2EE
應(yīng)用程序
-
Spring IDE 1.0.3
:
Spring Bean
配置管理插件
-
xmlbuddy_2.0.10
:編輯
XML
,用免費(fèi)版功能即可
-
tomcatPluginV3
:
tomcat
管理插件
-
Properties Editor
:編輯
java
的屬性文件
,
并可以預(yù)覽以及自動(dòng)存盤(pán)為
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)圖,更詳細(xì)的內(nèi)容請(qǐng)參見(jiàn)
JPetStore
的白皮書(shū)。參照這個(gè)架構(gòu)圖,讓我們稍微剖析一下源代碼,得出
JpetStore 4.0
的具體實(shí)現(xiàn)圖(見(jiàn)圖
2
),思路一下子就豁然開(kāi)朗了。前言中提到的非傳統(tǒng)的
struts
開(kāi)發(fā)模式,關(guān)鍵就在
struts Action
類(lèi)和
form bean
類(lèi)上。
struts Action
類(lèi)只有一個(gè):
BeanAction
。沒(méi)錯(cuò),確實(shí)是一個(gè)!與傳統(tǒng)的
struts
編程方式很不同。再仔細(xì)研究
BeanAction
類(lèi),發(fā)現(xiàn)它其實(shí)是一個(gè)通用類(lèi),利用反射原理,根據(jù)
URL
來(lái)決定調(diào)用
formbean
的哪個(gè)方法。
BeanAction
大大簡(jiǎn)化了
struts
的編程模式,降低了對(duì)
struts
的依賴(lài)(與
struts
以及
WEB
容器有關(guān)的幾個(gè)類(lèi)都放在
com.ibatis.struts
包下,其它的類(lèi)都可以直接復(fù)用)。利用這種模式,我們會(huì)很容易的把它移植到新的框架如
JSF
,
spring
。
這樣重心就轉(zhuǎn)移到
form bean
上了,它已經(jīng)不是普通意義上的
form bean
了。查看源代碼,可以看到它不僅僅有數(shù)據(jù)和校驗(yàn)
/
重置方法,而且已經(jīng)具有了行為,從這個(gè)意義上來(lái)說(shuō),它更像一個(gè)
BO(Business Object)
。這就是前文講到的,
BeanAction
類(lèi)利用反射原理,根據(jù)
URL
來(lái)決定調(diào)用
form bean
的哪個(gè)方法(行為)。
form bean
的這些方法的簽名很簡(jiǎn)單,例如:
|
方法的返回值直接就是字符串,對(duì)應(yīng)的是
forward
的名稱(chēng),而不再是
ActionForward
對(duì)象,創(chuàng)建
ActionForward
對(duì)象的任務(wù)已經(jīng)由
BeanAction
類(lèi)代勞了。
另外,程序還提供了
ActionContext
工具類(lèi),該工具類(lèi)封裝了
request
、
response
、
form parameters
、
request attributes
、
session attributes
和
application attributes
中的數(shù)據(jù)存取操作,簡(jiǎn)單而線程安全,
form bean
類(lèi)使用該工具類(lèi)可以進(jìn)一步從表現(xiàn)層框架解耦。
在這里需要特別指出的是,
BeanAction
類(lèi)是對(duì)
struts
擴(kuò)展的一個(gè)有益嘗試,雖然提供了非常好的應(yīng)用開(kāi)發(fā)模式,但是它還非常新,一直在發(fā)展中。
圖
2 JpetStore 4.0
具體實(shí)現(xiàn)
2.4.
代碼剖析
下面就讓我們開(kāi)始進(jìn)一步分析
JpetStore4.0
的源代碼,為下面的改造鋪路。
-
BeanAction.java
是唯一一個(gè)
Struts action
類(lèi),位于
com.ibatis.struts
包下。正如上文所言,它是一個(gè)通用的控制類(lèi),利用反射機(jī)制,把控制轉(zhuǎn)移到
form bean
的某個(gè)方法來(lái)處理。詳細(xì)處理過(guò)程參考其源代碼,簡(jiǎn)單明晰。
·????????
Form bean
類(lèi)位于
com.ibatis.jpetstore.presentation
包下,命名規(guī)則為
***Bean
。
Form bean
類(lèi)全部繼承于
BaseBean
類(lèi),而
BaseBean
類(lèi)實(shí)際繼承于
ActionForm
,因此,
Form bean
類(lèi)就是
Struts
的
ActionForm
,
Form bean
類(lèi)的屬性數(shù)據(jù)就由
struts
框架自動(dòng)填充。而實(shí)際上,
JpetStore4.0
擴(kuò)展了
struts
中
ActionForm
的應(yīng)用:
Form bean
類(lèi)還具有行為,更像一個(gè)
BO,
其行為(方法)由
BeanAction
根據(jù)配置(
struts-config.xml
)的
URL
來(lái)調(diào)用。雖然如此,我們還是把
Form bean
類(lèi)定位于表現(xiàn)層。
Struts-config.xml
的配置里有
3
種映射方式,來(lái)告訴
BeanAction
把控制轉(zhuǎn)到哪個(gè)
form bean
對(duì)象的哪個(gè)方法來(lái)處理。
以這個(gè)請(qǐng)求連接為例 http://localhost/jpetstore4/shop/viewOrder.do
1. URL Pattern
|
此種方式表示,控制將被轉(zhuǎn)發(fā)到
"orderBean"
這個(gè)
form bean
對(duì)象
的
"viewOrder"
方法(行為)來(lái)處理。方法名取
"path"
參數(shù)的以
"/"
分隔的最后一部分。
2. Method Parameter
|
此種方式表示,控制將被轉(zhuǎn)發(fā)到
"orderBean"
這個(gè)
form bean
對(duì)象的
"viewOrder"
方法(行為)來(lái)處理。配置中的
"parameter"
參數(shù)表示
form bean
類(lèi)上的方法。
"parameter"
參數(shù)優(yōu)先于
"path"
參數(shù)。
3. No Method call
|
此種方式表示,
form bean
上沒(méi)有任何方法被調(diào)用。如果存在
"name"
屬性,則
struts
把表單參數(shù)等數(shù)據(jù)填充到
form bean
對(duì)象后,把控制轉(zhuǎn)發(fā)到
"success"
。否則,如果
name
為空,則直接轉(zhuǎn)發(fā)控制到
"success"
。
這就相當(dāng)于
struts
內(nèi)置的
org.apache.struts.actions.ForwardAction
的功能
|
-
Service
類(lèi)位于
com.ibatis.jpetstore.service
包下,屬于業(yè)務(wù)層。這些類(lèi)封裝了業(yè)務(wù)以及相應(yīng)的事務(wù)控制。
Service
類(lèi)由
form bean
類(lèi)來(lái)調(diào)用。
-
com.ibatis.jpetstore.persistence.iface
包下的類(lèi)是
DAO
接口,屬于業(yè)務(wù)層,其屏蔽了底層的數(shù)據(jù)庫(kù)操作,供具體的
Service
類(lèi)來(lái)調(diào)用。
DaoConfig
類(lèi)是工具類(lèi)(
DAO
工廠類(lèi)),
Service
類(lèi)通過(guò)
DaoConfig
類(lèi)來(lái)獲得相應(yīng)的
DAO
接口,而不用關(guān)心底層的具體數(shù)據(jù)庫(kù)操作,實(shí)現(xiàn)了如圖
2
中
{
耦合
2}
的解耦。
-
com.ibatis.jpetstore.persistence.sqlmapdao
包下的類(lèi)是對(duì)應(yīng)
DAO
接口的具體實(shí)現(xiàn),在
JpetStore4.0
中采用了
ibatis
來(lái)實(shí)現(xiàn)
ORM
。這些實(shí)現(xiàn)類(lèi)繼承
BaseSqlMapDao
類(lèi),而
BaseSqlMapDao
類(lèi)則繼承
ibatis DAO
框架中的
SqlMapDaoTemplate
類(lèi)。
ibatis
的配置文件存放在
com.ibatis.jpetstore.persistence.sqlmapdao.sql
目錄下。這些類(lèi)和配置文件位于數(shù)據(jù)層
-
Domain
類(lèi)位于
com.ibatis.jpetstore.domain
包下,是普通的
javabean
。在這里用作數(shù)據(jù)傳輸對(duì)象(
DTO
),貫穿視圖層、業(yè)務(wù)層和數(shù)據(jù)層,用于在不同層之間傳輸數(shù)據(jù)。
剩下的部分就比較簡(jiǎn)單了,請(qǐng)看具體的源代碼,非常清晰。
2.5.
需要改造的地方
JpetStore4.0
的關(guān)鍵就在
struts Action
類(lèi)和
form bean
類(lèi)上,這也是其精華之一(雖然該實(shí)現(xiàn)方式是試驗(yàn)性,待擴(kuò)充和驗(yàn)證),在此次改造中我們要保留下來(lái),即控制層一點(diǎn)不變,表現(xiàn)層獲取相應(yīng)業(yè)務(wù)類(lèi)的方式變了(要加載
spring
環(huán)境),其它保持不變。要特別關(guān)注的改動(dòng)是業(yè)務(wù)層和持久層,幸運(yùn)的是
JpetStore4.0
設(shè)計(jì)非常好,需要改動(dòng)的地方非常少,而且由模式可循,如下:
1.
業(yè)務(wù)層和數(shù)據(jù)層用
Spring BeanFactory
機(jī)制管理。
2.
業(yè)務(wù)層的事務(wù)由
spring
的
aop
通過(guò)聲明來(lái)完成。
3.
表現(xiàn)層(
form bean
)獲取業(yè)務(wù)類(lèi)的方法改由自定義工廠類(lèi)來(lái)實(shí)現(xiàn)(加載
spring
環(huán)境)。
3. JPetStore
的改造
3.1.
改造后的架構(gòu)
其中紅色部分是要增加的部分,藍(lán)色部分是要修改的部分。下面就讓我們逐一剖析。
3.2. Spring Context
的加載
為了在
Struts
中加載
Spring Context
,一般會(huì)在
struts-config.xml
的最后添加如下部分:
|
Spring
在設(shè)計(jì)時(shí)就充分考慮到了與
Struts
的協(xié)同工作,通過(guò)內(nèi)置的
Struts Plug-in
在兩者之間提供了良好的結(jié)合點(diǎn)。但是,因?yàn)樵谶@里我們一點(diǎn)也不改動(dòng)
JPetStore
的控制層
(
這是
JpetStore4.0
的精華之一
)
,所以本文不準(zhǔn)備采用此方式來(lái)加載
ApplicationContext
。我們利用的是
spring framework
的
BeanFactory
機(jī)制
,
采用自定義的工具類(lèi)(
bean
工廠類(lèi))來(lái)加載
spring
的配置文件,從中可以看出
Spring
有多靈活,它提供了各種不同的方式來(lái)使用其不同的部分
/
層次,您只需要用你想用的,不需要的部分可以不用。
具體的來(lái)說(shuō),就是在
com.ibatis.spring
包下創(chuàng)建
CustomBeanFactory
類(lèi),
spring
的配置文件
applicationContext.xml
也放在這個(gè)目錄下。以下就是該類(lèi)的全部代碼,很簡(jiǎn)單:
|
實(shí)際上就是封裝了
Spring
的
XMLBeanFactory
而已,并且
Spring
的配置文件只需要加載一次,以后就可以直接用
CustomBeanFactory.getBean("someBean")
來(lái)獲得需要的對(duì)象了
(
例如
someBean)
,而不需要知道具體的類(lèi)。
CustomBeanFactory
類(lèi)用于
{
耦合
1}
的解耦。
CustomBeanFactory
類(lèi)在本文中只用于表現(xiàn)層的
form bean
對(duì)象獲得
service
類(lèi)的對(duì)象,因?yàn)槲覀儧](méi)有把
form bean
對(duì)象配置在
applicationContext.xml
中。但是,為什么不把表現(xiàn)層的
form bean
類(lèi)也配置起來(lái)呢,這樣就用不著這
CustomBeanFactory
個(gè)類(lèi)了,
Spring
會(huì)幫助我們創(chuàng)建需要的一切?問(wèn)題的答案就在于
form bean
類(lèi)是
struts
的
ActionForm
類(lèi)!如果大家熟悉
struts
,就會(huì)知道
ActionForm
類(lèi)是
struts
自動(dòng)創(chuàng)建的:在一次請(qǐng)求中,
struts
判斷,如果
ActionForm
實(shí)例不存在,就創(chuàng)建一個(gè)
ActionForm
對(duì)象,把客戶(hù)提交的表單數(shù)據(jù)保存到
ActionForm
對(duì)象中。因此
formbean
類(lèi)的對(duì)象就不能由
spring
來(lái)創(chuàng)建,但是
service
類(lèi)以及數(shù)據(jù)層的
DAO
類(lèi)可以,所以只有他們?cè)?/font>
spring
中配置。
所以,很自然的,我們就創(chuàng)建了
CustomBeanFactory
類(lèi),在表現(xiàn)層來(lái)銜接
struts
和
spring
。就這么簡(jiǎn)單,實(shí)現(xiàn)了另一種方式的
{
耦合一
}
的解耦。
3.3.
表現(xiàn)層
面分析到,
struts
和
spring
是在表現(xiàn)層銜接起來(lái)的,那么表現(xiàn)層就要做稍微的更改,即所需要的
service
類(lèi)的對(duì)象創(chuàng)建上。以表現(xiàn)層的
AccountBean
類(lèi)為例:
上
原來(lái)的源代碼如下
|
改造后的源代碼如下
|
其他的幾個(gè)
presentation
類(lèi)以同樣方式改造。這樣,表現(xiàn)層就完成了。關(guān)于表現(xiàn)層的其它部分如
JSP
等一概不動(dòng)。也許您會(huì)說(shuō),沒(méi)有看出什么特別之處的好處啊?你還是額外實(shí)現(xiàn)了一個(gè)工廠類(lèi)。別著急,帷幕剛剛開(kāi)啟,
spring
是在表現(xiàn)層引入,但您發(fā)沒(méi)發(fā)現(xiàn):
-
presentation
類(lèi)僅僅面向
service
類(lèi)的接口編程,具體
"AccountService"
是哪個(gè)實(shí)現(xiàn)類(lèi),
presentation
類(lèi)不知道,是在
spring
的配置文件里配置。(本例中,為了最大限度的保持原來(lái)的代碼不作變化,沒(méi)有抽象出接口)。
Spring
鼓勵(lì)面向接口編程,因?yàn)槭侨绱说姆奖愫妥匀唬?dāng)然您也可以不這么做。
-
CustomBeanFactory
這個(gè)工廠類(lèi)為什么會(huì)如此簡(jiǎn)單,因?yàn)槠渲苯邮褂昧?/span>
Spring
的
BeanFactory
。
Spring
從其核心而言,是一個(gè)
DI
容器,其設(shè)計(jì)哲學(xué)是提供一種無(wú)侵入式的高擴(kuò)展性的框架。為了實(shí)現(xiàn)這個(gè)目標(biāo),
Spring
大量引入了
Java
的
Reflection
機(jī)制,通過(guò)動(dòng)態(tài)調(diào)用的方式避免硬編碼方式的約束,并在此基礎(chǔ)上建立了其核心組件
BeanFactory
,以此作為其依賴(lài)注入機(jī)制的實(shí)現(xiàn)基礎(chǔ)。
org.springframework.beans
包中包括了這些核心組件的實(shí)現(xiàn)類(lèi),核心中的核心為
BeanWrapper
和
BeanFactory
類(lèi)。
3.4.
持久層
在討論業(yè)務(wù)層之前,我們先看一下持久層,如下圖所示:
在上文中,我們把
iface
包下的
DAO
接口歸為業(yè)務(wù)層,在這里不需要做修改。
ibatis
的
sql
配置文件也不需要改。要改的是
DAO
實(shí)現(xiàn)類(lèi),并在
spring
的配置文件中配置起來(lái)。
1
、修改基類(lèi)
所有的
DAO
實(shí)現(xiàn)類(lèi)都繼承于
BaseSqlMapDao
類(lèi)。修改
BaseSqlMapDao
類(lèi)如下:
|
使 BaseSqlMapDao 類(lèi)改為繼承于 Spring 提供的 SqlMapClientDaoSupport 類(lèi),并定義了一個(gè)保護(hù)屬性 smcTemplate ,其類(lèi)型為 SqlMapClientTemplate 。關(guān)于 SqlMapClientTemplate 類(lèi)的詳細(xì)說(shuō)明請(qǐng)參照附錄中的 "Spring 中文參考手冊(cè) "
2
、修改
DAO
實(shí)現(xiàn)類(lèi)
所有的
DAO
實(shí)現(xiàn)類(lèi)還是繼承于
BaseSqlMapDao
類(lèi),實(shí)現(xiàn)相應(yīng)的
DAO
接口,但其相應(yīng)的
DAO
操作委托
SqlMapClientTemplate
來(lái)執(zhí)行,以
AccountSqlMapDao
類(lèi)為例,部分代碼如下:
|
就這么簡(jiǎn)單,所有函數(shù)的簽名都是一樣的,只需要查找替換就可以了!
3
、除去工廠類(lèi)以及相應(yīng)的配置文件
除去
DaoConfig.java
這個(gè)
DAO
工廠類(lèi)和相應(yīng)的配置文件
dao.xml
,因?yàn)?/font>
DAO
的獲取現(xiàn)在要用
spring
來(lái)管理。
4
、
DAO
在
Spring
中的配置(
applicationContext.xml
)
|
具體的語(yǔ)法請(qǐng)參照附錄中的
"Spring
中文參考手冊(cè)
"
。在這里只簡(jiǎn)單解釋一下:
1.
我們首先創(chuàng)建一個(gè)數(shù)據(jù)源
dataSource
,在這里配置的是
hsqldb
數(shù)據(jù)庫(kù)。如果是
ORACLE
數(shù)據(jù)庫(kù),
driverClassName
的值是
"oracle.jdbc.driver.OracleDriver"
,
URL
的值類(lèi)似于
"jdbc:oracle:thin:@wugfMobile:1521:cdcf"
。數(shù)據(jù)源現(xiàn)在由
spring
來(lái)管理,那么現(xiàn)在我們就可以去掉
properties
目錄下
database.properties
這個(gè)配置文件了;還有不要忘記修改
sql-map-config.xml
,去掉
<properties resource="properties/database.properties"/>
對(duì)它的引用。
2. sqlMapClient
節(jié)點(diǎn)。這個(gè)是針對(duì)
ibatis SqlMap
的
SqlMapClientFactoryBean
配置。實(shí)際上配置了一個(gè)
sqlMapClient
的創(chuàng)建工廠類(lèi)。
configLocation
屬性配置了
ibatis
映射文件的名稱(chēng)。
dataSource
屬性指向了使用的數(shù)據(jù)源,這樣所有使用
sqlMapClient
的
DAO
都默認(rèn)使用了該數(shù)據(jù)源,除非在
DAO
的配置中另外顯式指定。
3. TransactionManager
節(jié)點(diǎn)。定義了事務(wù),使用的是
DataSourceTransactionManager
。
4.
下面就可以定義
DAO
節(jié)點(diǎn)了,如
AccountDao
,它的實(shí)現(xiàn)類(lèi)是
com.ibatis.jpetstore.persistence.sqlmapdao.AccountSqlMapDao
,使用的
SQL
配置從
sqlMapClient
中讀取,數(shù)據(jù)庫(kù)連接沒(méi)有特別列出,那么就是默認(rèn)使用
sqlMapClient
配置的數(shù)據(jù)源
datasource
。
這樣,我們就把持久層改造完了,其他的
DAO
配置類(lèi)似于
AccountDao
。怎么樣?簡(jiǎn)單吧。這次有接口了:)
AccountDao
接口-
>AccountSqlMapDao
實(shí)現(xiàn)。
3.5.
業(yè)務(wù)層
業(yè)務(wù)層的位置以及相關(guān)類(lèi),如下圖所示:
在這個(gè)例子中只有
3
個(gè)業(yè)務(wù)類(lèi),我們以
OrderService
類(lèi)為例來(lái)改造,這個(gè)類(lèi)是最復(fù)雜的,其中涉及了事務(wù)。
1
、在
ApplicationContext
配置文件中增加
bean
的配置:
|
定義了一個(gè)
OrderService
,還是很容易懂的。為了簡(jiǎn)單起見(jiàn),使用了嵌套
bean
,其實(shí)現(xiàn)類(lèi)是
com.ibatis.jpetstore.service.OrderService
,分別引用了
ItemDao
,
OrderDao
,
SequenceDao
。該
bean
的
insert*
實(shí)現(xiàn)了事務(wù)管理
(AOP
方式
)
。
TransactionProxyFactoryBean
自動(dòng)創(chuàng)建一個(gè)事務(wù)
advisor
,
該
advisor
包括一個(gè)基于事務(wù)屬性的
pointcut,
因此只有事務(wù)性的方法被攔截。
2
、業(yè)務(wù)類(lèi)的修改
以
OrderService
為例:
|
紅色部分為修改部分。
Spring
采用的是
Type2
的設(shè)置依賴(lài)注入,所以我們只需要定義屬性和相應(yīng)的設(shè)值函數(shù)就可以了,
ItemDao
,
OrderDao
,
SequenceDao
的值由
spring
在運(yùn)行期間注入。構(gòu)造函數(shù)就可以為空了,另外也不需要自己編寫(xiě)代碼處理事務(wù)了(事務(wù)在配置中聲明),
daoManager.startTransaction();
等與事務(wù)相關(guān)的語(yǔ)句也可以去掉了。和原來(lái)的代碼比較一下,是不是處理精簡(jiǎn)了很多!可以更關(guān)注業(yè)務(wù)的實(shí)現(xiàn)。
4.
結(jié)束語(yǔ)
ibatis
是一個(gè)功能強(qiáng)大實(shí)用的
SQL Map
工具,可以直接控制
SQL,
為系統(tǒng)設(shè)計(jì)提供了更大的自由空間。其提供的最新示例程序
JpetStore 4.0,
設(shè)計(jì)優(yōu)雅,應(yīng)用了迄今為止很多最佳實(shí)踐和設(shè)計(jì)模式,非常適于學(xué)習(xí)以及在此基礎(chǔ)上創(chuàng)建輕量級(jí)的
J2EE WEB
應(yīng)用程序。
JpetStore 4.0
是基于
struts
的,本文在此基礎(chǔ)上,最大程度保持了原有設(shè)計(jì)的精華以及最小的代碼改動(dòng)量,在業(yè)務(wù)層和持久化層引入了
Spring
。在您閱讀了本文以及改造后的源代碼后,會(huì)深切的感受到
Spring
帶來(lái)的種種好處:自然的面向接口的編程,業(yè)務(wù)對(duì)象的依賴(lài)注入,一致的數(shù)據(jù)存取框架和聲明式的事務(wù)處理,統(tǒng)一的配置文件…更重要的是
Spring
既是全面的又是模塊化的,
Spring
有分層的體系結(jié)構(gòu),這意味著您能選擇僅僅使用它任何一個(gè)獨(dú)立的部分,就像本文,而它的架構(gòu)又是內(nèi)部一致。
參考資料
-
jpetstore
相關(guān)各種資料和源程序
http://www.ibatis.com/jpetstore/jpetstore.html
-
Spring
中文參考手冊(cè)
http://www.jactiongroup.net/reference/html/index.html
-
Spring
開(kāi)發(fā)指南
夏昕
- Struts http://struts.apache.org/
??????作者Blog:http://blog.csdn.net/yanwp/