[feiq]Springside_3.3.2_技術(shù)參考手冊(cè)_第1頁(yè)
[feiq]Springside_3.3.2_技術(shù)參考手冊(cè)_第2頁(yè)
[feiq]Springside_3.3.2_技術(shù)參考手冊(cè)_第3頁(yè)
[feiq]Springside_3.3.2_技術(shù)參考手冊(cè)_第4頁(yè)
[feiq]Springside_3.3.2_技術(shù)參考手冊(cè)_第5頁(yè)
已閱讀5頁(yè),還剩65頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Springside 3.3.2 技術(shù)參考手冊(cè)自己的總結(jié): Springside3中的struts21、使用CodeBehind插件來(lái)簡(jiǎn)化配置。使用CodeBehind后,我們就可以不用配置result了,它可以根據(jù)我們Action的返回 值自動(dòng)猜測(cè)返回的視圖頁(yè)面,它猜測(cè)的規(guī)則是這樣的:返回頁(yè)面的路徑為struts.codebehind.pathPrefix + package namespace + action name + action returnvalue+.jsp,action returnvalue為success時(shí),值為空,為其他時(shí),值為- + return type。我們來(lái)看

2、看SpringSide 3生成的項(xiàng)目中關(guān)于Struts 2的配置文件:其 中struts.codebehind.pathPrefix設(shè)置為“/WEB-INF/jsp/”,package的namespace沒(méi)有設(shè)置,所 以,如果我們的Action為UserAction,則返回success時(shí),就會(huì)返回到/WEB-INF/jsp/user.jsp,如果返回 input,則返回到/WEB-INF/jsp/user-input.jsp。這里江南白衣玩了一個(gè)狡猾,他把所有的jsp頁(yè)面放到WEB-INF目錄 中,別人就沒(méi)有辦法直接訪問(wèn)了,這樣就可以簡(jiǎn)化Acegi的配置工作。2、關(guān)于攔截器棧在上面講Stru

3、ts 2的特點(diǎn)時(shí),我已經(jīng)說(shuō)了Struts 2中攔截器的重要作用,在上面的截圖中,package的配置沒(méi)有做別的什么事,主要就是配置了攔截器棧。那么攔截器棧是怎么使用的呢?它是在 Action類中通過(guò)ParentPackage指定的,如下面的代碼:下面,我來(lái)具體說(shuō)一下攔截器有什么作用。例子一、我們知道Struts 2中的Action是和Servlet API解耦的,那么如果我們要在Action中訪問(wèn)Servlet API怎么辦呢?一種辦法就是使用ServletActionContext,如下圖:另外一種辦法,就是讓我們的Action實(shí)現(xiàn)ServletRequestAware接口,如下代碼:pub

4、lic class MyAction implements ServletRequestAware private HttpServletRequestrequest; public void setServletRequest(HttpServletRequestrequest) this .request = request; public Stringexecute() throws Exception / dotheworkusingtherequest return Action.SUCCESS; 這時(shí)候,ServletConfigInterceptor 攔截器就會(huì)把request對(duì)

5、象注入到我們的Action中。例子二、ParametersInterceptor 攔截器會(huì)自動(dòng)解析web表單或URL參數(shù),并把它們注入到Action中。但是很多時(shí)候,我們不愿意我們的Action具有太多的屬性,因?yàn)橐淮蠖训?get、set方法看起來(lái)太亂糟糟,我們希望有一個(gè)專門的Model對(duì)象來(lái)存儲(chǔ)這些值,而且剛好我們?yōu)镠ibernate設(shè)計(jì)的Entity類用來(lái)做 Model正合適。這時(shí),我們可以讓我們的Action實(shí)現(xiàn)ModelDriven接口,讓getModel()方法返回我們的entity對(duì)象即可。這正是SpringSide 3采取的方法,如下圖的代碼片斷:這時(shí)候,ModelDrivenI

6、nterceptor攔截器就會(huì)幫助我們把解析的URL參數(shù)或表單數(shù)據(jù)注入到entity的屬性中,而不是Action中。例子三、Preparable 接口聯(lián)合PrepareInterceptor攔截器一起工作,可以讓action在執(zhí)行execute() 方法前, 執(zhí)行一個(gè)prepare()方法,這也正是SpringSide 3的工作方式。3、關(guān)于Action有了上面對(duì)CodeBehind的理解和對(duì)攔截器棧的理解后,再來(lái)理解SpringSide 3中的Action就再簡(jiǎn)單不過(guò)了,SpringSide 3中Action的繼承樹(shù)如下:其中ActionSupport類是Struts 2提供的,另外兩個(gè)類是

7、白衣自己擴(kuò)展的。其中SimpleActionSupport主要是提供了一些繞過(guò)jsp頁(yè)面直接輸出字符串的方法,不值一談。而CRUDActionSupport就比較復(fù)雜,如下: publicabstractclassCRUDActionSupportextendsSimpleActionSupportimplementsModelDriven,Preparable/*進(jìn)行CUD操作后,以redirect方式重新打開(kāi)action默認(rèn)頁(yè)的result名.*/publicstaticfinalStringRELOAD=reload;/*Action函數(shù),默認(rèn)action函數(shù),默認(rèn)指向list函數(shù).*/

8、OverridepublicStringexecute()throwsExceptionreturnlist();/*Action函數(shù),顯示Entity列表.*returnSUCCESS.*/publicabstractStringlist()throwsException;/*Action函數(shù),新增或修改Entity.*returnRELOAD.*/publicabstractStringsave()throwsException;/*Action函數(shù),刪除Entity.*returnRELOAD.*/publicabstractStringdelete()throwsException;/

9、*在save()前執(zhí)行二次綁定.*/publicvoidprepareSave()throwsExceptionprepareModel();/*在input()前執(zhí)行二次綁定.*/publicvoidprepareInput()throwsExceptionprepareModel();/*屏蔽公共的二次綁定.*/publicvoidprepare()throwsException/*等同于prepare()的內(nèi)部函數(shù).*/protectedabstractvoidprepareModel()throwsException;第 一,它做了把CRUD操作放到了同一個(gè)Action中的操作,這樣可

10、以少寫(xiě)幾個(gè)Action。這個(gè)工作難度不大,我覺(jué)得白衣此舉,主要是為了規(guī)范CRUD 函數(shù)的命名。在Struts 2中,如果我們要訪問(wèn)的不是默認(rèn)的excute方法,可以使用如/user!save.action的格式,這樣訪問(wèn)的就是UserAction的 save方法。第二,它實(shí)現(xiàn)了ModelDriven接口和Preparable接 口,關(guān)于這兩個(gè)接口,我在前面講攔截器的時(shí)候已經(jīng)提到過(guò)了,所以很容易理解。我們可以把我們?yōu)镠ibernate設(shè)計(jì)的entity類作為Model,也 可以把初始化這些entity的工作放到prepareSave()和prepareInput()方法中,這兩個(gè)方法將會(huì)在sav

11、e()和 input()方法執(zhí)行前自動(dòng)執(zhí)行。第三,它定義了一個(gè)靜態(tài)變量RELOAD,定義這個(gè)變量的目的是為了定義一個(gè)result的需要。CodeBehind中,大部分的result可以自己猜測(cè),對(duì)于不能猜測(cè)的,需要使用Results指定,如下代碼:2.實(shí)例分析: publicStringlist()throwsExceptionpage=articleManager.getAll(page);returnSUCCESS;該方法單純的獲取所有l(wèi)ist,可以調(diào)用getAll()方法即可,如果要實(shí)現(xiàn)復(fù)雜的條件查詢,就需要?jiǎng)?chuàng)建一個(gè)包含PropertyFilter對(duì)象的列表,然后使用articleMan

12、ager.search方法進(jìn)行查詢,為了簡(jiǎn)化PropertyFilter對(duì)象列表的創(chuàng)建,白衣提供了 HibernateWebUtils.buildPropertyFilters()靜態(tài)方法供大家使用。1. 總述 架構(gòu)風(fēng)格簡(jiǎn)述1.概述 技術(shù)框架選型以工業(yè)化大規(guī)模軟件開(kāi)發(fā)為原則-主流的選型、適宜團(tuán)隊(duì)分工的架構(gòu),同時(shí)照顧輕量級(jí)快速開(kāi)發(fā)的需求,Java版的約定大于配置的風(fēng)格。 SpringSide 3 的進(jìn)步(京山游俠)在SpringSide的官方主頁(yè)上,寫(xiě)著SpringSide 3 中包含的主流組件:Spring 2.5 + Hibernate 3 + Struts 2 + JSP 2.0 + JQ

13、uery + JAX-WS 2 (by Apache CXF 2) +SpringSecurity 2.0。不過(guò),如果你認(rèn)為和SpringSide 2 相比,升級(jí)的只是版本號(hào),那么你就大錯(cuò)特錯(cuò)了。像我這樣從SpringSide 2過(guò)來(lái)的人,如果能夠詳細(xì)對(duì)比SpringSide 2 和SpringSide 3,對(duì)于我們理解SpringSide 3肯定更加有幫助。下面的內(nèi)容是我自己的一些體會(huì),不正確的地方歡迎大家指正。從主要的架構(gòu)來(lái),依然是那么幾層,先設(shè)計(jì)數(shù)據(jù)庫(kù),再寫(xiě) Entity層,再寫(xiě)Dao層,再寫(xiě)Action,然后使用JSP表現(xiàn)出來(lái),其中的Entity和Dao層和Hibernate緊密相關(guān),

14、Action是 Struts的主要部分,Spring作為粘合劑,把這些東西連在一起,并提供了一些機(jī)制簡(jiǎn)化編寫(xiě)這些層的工作。SpringSide就是這樣一個(gè)大的粘 合體,省去了我們自己很多的粘合工作。從SpringSide 2 到SpringSide 3,這些工作得到進(jìn)一步的簡(jiǎn)化,我們開(kāi)發(fā)起來(lái)就更爽了。我 認(rèn)為,我們的開(kāi)發(fā)模式,主要經(jīng)歷了這樣的簡(jiǎn)化過(guò)程:第一階段,代碼加一大堆的配置文件第 二階段,代碼加少量的配置文件第三階段,代碼加基本上等于零的配置文件這 些進(jìn)步是如何實(shí)現(xiàn)的呢?從第一階段到第二階段,主要靠的是Annotation,把一些大量的配置工作轉(zhuǎn)移到了Java代碼中,那么從第二階段到第三

15、階段 怎么實(shí)現(xiàn)呢?都已經(jīng)Annotation了,你還有什么辦法讓配置文件更少?想不到吧!我也想不到,直到我看了SpringSide 3生成的項(xiàng)目,我才知道還有一個(gè)好東西叫自動(dòng)掃描。下面使用實(shí)際的例子進(jìn)行說(shuō)明。作為示例,Hibernate是個(gè)不錯(cuò)的選擇。第 一階段,如果單獨(dú)使用Hibernate,我們每寫(xiě)一個(gè)Entity類,就得同時(shí)寫(xiě)一個(gè).hbm.xml文件,如果有很多Entity,就得寫(xiě)很 多.hbm.xml文件,每修改一次Entity,也要同時(shí)記得修改.hbm.xml文件,相當(dāng)?shù)牟环奖悖淠夸浗Y(jié)構(gòu)如下圖:第二階段,使用 Annotation,SpringSide 2 中就是這樣的方式。具體內(nèi)

16、容可以看我的另一篇博文打通持久層的任督二脈。所以我用SpringSide 2 進(jìn)行開(kāi)發(fā)的時(shí)候,寫(xiě)Entity也是兩個(gè)步驟,但是比第一階段要簡(jiǎn)單。就是先寫(xiě)一個(gè)Entity,Entity里面使用Annotation,如下圖:然后修改配置文件,SpringSide 2 中專門為Hibernate的定義開(kāi)辟了一個(gè)專門的xml文件dataAccessContext-hibernate.xml,里面關(guān)于 SessionFactory的定義是我們很熟悉的。我只需要將我的Entity類加入到里面就可以了,如下圖中紅筆圈出來(lái)的部分:第二階段和第一階段相比,配置文件簡(jiǎn)單多了,不需要維護(hù)那 么多的.hbm.xml。

17、但是,每編寫(xiě)一個(gè)Entity,依然需要修改一下配置文件。第三階段就更了不起了,零配置文件,也就是說(shuō)我們只 管寫(xiě)Entity就行了,不需要管配置文件(當(dāng)然,項(xiàng)目開(kāi)始的時(shí)候還是要配置一次的)。打開(kāi)SpringSide 3生成的項(xiàng)目,果然找不到dataAccessContext-hibernate.xml文件。那么是如何實(shí)現(xiàn)零配置的呢?靠的就是自動(dòng)掃描,如下圖中 紅筆圈出來(lái)的部分:上面講Hibernate只是為了舉例說(shuō)明我的觀點(diǎn),事 實(shí)上SpringSide 3 中的零配置可不僅僅只存在這一個(gè)地方。Dao層也可以不用配置了。在SpringSide 2 中,我們每寫(xiě)一個(gè)Dao,都需要在serviceC

18、ontext.xml中加入這個(gè)類,如下圖:SpringSide 3 中使用自動(dòng)掃描了,如下圖:以后編寫(xiě)Service后,再也不用修改配置文件了,只要 我們?cè)赟ervice中使用如下Annotation:事務(wù)也不用配置了,在SpringSide 2 中,事務(wù)是這樣配置的:SpringSide 3 中,事務(wù)配置是這樣的:Action也不用配置了,不 過(guò)使得Action零配置的代碼卻在web.xml中,如下圖:還記得SpringSide 2 中的Struts配置代碼嗎?編寫(xiě)完Action類的代碼后,還需要修改兩個(gè)配置文件,如下:所以說(shuō),SpringSide 3 的一個(gè)優(yōu)點(diǎn)就是讓生活變得更加簡(jiǎn)單了。在

19、以上的截圖中,SpringSide 2 項(xiàng)目用的是Eclipse 3.2,而SpringSide 3項(xiàng)目用的是Eclipse 3.4 For JavaEE Developers。哪一個(gè)IDE更爽,那也是一目了然。2.主要庫(kù)棧 JDK:JDK 6.0、 UTF-8. IOC container:Spring 3. ORM:Hibernate 3.3. Web :Struts 2.1、JSP 2.0、JQuery 1.4/Dojo Base 1.4. Web Service:基于Apache CXF 2.2的JAX-WS/JAXB 2.0規(guī)范, 基于Jersey的JAX-RS規(guī)范. Securit

20、y: Spring Security 3.0.3.層次說(shuō)明3.1 entity - 領(lǐng)域模型層 使用Sql First的開(kāi)發(fā)模式,先設(shè)計(jì)數(shù)據(jù)庫(kù),參考DBA的性能意見(jiàn)而不要太片面追求OO化的表結(jié)構(gòu)。 然后純手工編寫(xiě)entity與極少量的JPA annotation(約定大于配置), 也可以用hibernate-tools從數(shù)據(jù)庫(kù)逆向生成后再作修改。3.2 access - 資源訪問(wèn)層 資源訪問(wèn)層包括對(duì)數(shù)據(jù)庫(kù)、JMS、外部的WebService等的訪問(wèn)。 每個(gè)領(lǐng)域?qū)ο髮?duì)應(yīng)一個(gè)DAO類,繼承于通用的HibernateDao,所有以該對(duì)象為查詢主體的HQL語(yǔ)句統(tǒng)一定義于DAO內(nèi)并提供 查詢函數(shù). 在性

21、能緊要而Hibernate又無(wú)法滿足要求時(shí),可混合使用JDBCTemplate。3.3 service - 業(yè)務(wù)邏輯層 Service層有兩類對(duì)象, 一類是領(lǐng)域?qū)ο蠊芾眍?Entity Manager), 按領(lǐng)域?qū)ο髣澐?,每個(gè)Manager類負(fù)責(zé)管理多個(gè)緊密關(guān)聯(lián)的Entity的增刪改查及其業(yè)務(wù)邏輯。 一類是業(yè)務(wù)服務(wù)類(Service),按業(yè)務(wù)腳本劃分,可能會(huì)訪問(wèn)到多種領(lǐng)域?qū)ο笈cManager類。 用Spring的Transcation annotation定義事務(wù)。 對(duì)于Hibernate Lazy load的關(guān)聯(lián)對(duì)象,在性能要求不高時(shí)可使用OpenSessionInView Filter,否

22、則在Service層完成對(duì)象的初始化操作。3.4 web - Web MVC層 MVC框架使用Struts 2.1 這一老牌傳統(tǒng)MVC框架 + Convention Plugin 實(shí)現(xiàn)零配置文件,每個(gè)Action實(shí)現(xiàn)一組頁(yè)面操作。 View模板用JSP2.0 , 盡量使用純html+JSP2.0 EL展示頁(yè)面。 Javascript與Ajax使用JQuery或Dojo Base。 盡量采用CSS框架規(guī)范CSS的布局。3.5 ws - WebService接口 使用Java first的開(kāi)發(fā)模式,通過(guò)JSR181 annotation標(biāo)注Web Service接口,用JAXB-2.0 annot

23、ation標(biāo)注Java-XML Mapping。 用DTO類實(shí)現(xiàn)Entity與外系統(tǒng)的解耦,用WSResult包裹返回結(jié)果與返回碼,不使用Exception返回錯(cuò)誤。 對(duì)于Restful服務(wù),同樣采用JAX-RS annotation標(biāo)注。3.6 security - 安全控制 使用Spring Security的Filter 攔截URL,使用Spirng Security的taglib 攔截頁(yè)面內(nèi)容。 采用 用戶-角色-資源 三層控制,角色-資源關(guān)系定義于XML的簡(jiǎn)化模式。3.7 測(cè)試 單元測(cè)試盡量采用MockObject的方式屏幕所有依賴對(duì)象/數(shù)據(jù)的訪問(wèn),對(duì)于dao層與特別查詢與特別數(shù)據(jù)庫(kù)

24、操作,采用集成測(cè)試連接實(shí)際數(shù)據(jù)庫(kù),基于 Spring的集成測(cè)試Context。 功能測(cè)試使用selenium測(cè)試主要用戶故事的主流程及Javascript的效果, 使用Jetty嵌入式Web服務(wù)器與H2嵌入式數(shù)據(jù)庫(kù),使用DBUnit預(yù)備數(shù)據(jù),使得整個(gè)測(cè)試可以快速運(yùn)行,對(duì)測(cè)試環(huán)境沒(méi)有太多的依賴。4.常見(jiàn)問(wèn)題4.1 什么時(shí)候使用基于接口編程 ? 基于接口編程、Fascade層等等抽象封裝都是有開(kāi)發(fā)和維護(hù)的代價(jià)的,是否使用歸根結(jié)底還是看在團(tuán)隊(duì)人員的分工情況,在大家不得不依賴這幾項(xiàng)技術(shù)來(lái)解決 相互的接口、契約問(wèn)題時(shí),自然就用了。4.2 Package是先分層還是先分模塊 org.springside.

25、模塊A.web 還是 org.springside.web.模塊A? 同上,還是看團(tuán)隊(duì)人員的分工情況。如果是每人從頭到尾負(fù)責(zé)一個(gè)獨(dú)立模塊的可以先分模塊。反之,按層進(jìn)行分工并鼓勵(lì)層內(nèi)重用的,可以考慮先分層。 目錄結(jié)構(gòu)描述1.公共目錄結(jié)構(gòu) 完全采用maven的默認(rèn)布局。bin 命令腳本目錄,詳見(jiàn)后。 src main 主源碼目錄 main/java java源文件 main/resources 配置文件、屬性文件 main/webapp Web應(yīng)用目錄 test 測(cè)試目錄,結(jié)構(gòu)與主源碼目錄相同 unit 單元測(cè)試 functional 功能測(cè)試 data 測(cè)試數(shù)據(jù)生成器 target maven編

26、譯目錄 2.bin目錄結(jié)構(gòu)文件 描述 db-export / db-init 將當(dāng)前數(shù)據(jù)庫(kù)數(shù)據(jù)通過(guò)dbunit導(dǎo)出到export-data.xml。 執(zhí)行src/main/sql 中的腳本初始化數(shù)據(jù)庫(kù)schema,再通過(guò)dbunit執(zhí)行default-data.xml初始化數(shù)據(jù)。 convert-h2 將真正數(shù)據(jù)庫(kù)的sql轉(zhuǎn)換為測(cè)試用的H2的sql。 eclipse 生成Eclipse項(xiàng)目文件。 jetty / Jetty-debug 用jetty快速運(yùn)行本項(xiàng)目。 jetty-debug支持eclipse以debug方式連入,端口為8000 hibernate/generate code 從數(shù)

27、據(jù)庫(kù)逆向生成entity / dao / pojo 2. 基礎(chǔ)框架 Spring: Spring Framework1. 參考資料 Spring資料(江南白衣博物館)1.圖書(shū) Spring 2.5 參考手冊(cè)中文版(英文版) (滿江紅出品) Spring Recipes - A Problem-Solution Approach Apress,20082.文章 Introduction to the Spring Framework 2.5 (TSS) Rod 老大的Spring介紹 Spring 2.5版。3.筆記 Spring2.5的筆記 以前的筆記part1、part2、part3有時(shí)間會(huì)

28、 根據(jù)Spring的最新變化重新整理。 Spring 2.5 參考手冊(cè)中文版(滿江紅出品) Spring Recipes - A Problem-Solution Approach Apress,2008 Spring 2中較好的參考書(shū)。2. 選型 有人說(shuō)guice好,但我們用Spring不僅是為了IOC,也為了Spring對(duì)JEE所做的封裝,以及整個(gè)JavaEE界眾多項(xiàng)目 (SpringSecurity,CXF、Struts2等)對(duì)它的依賴。3. in SpringSide 3 - Mini示例使用的基本特性 屬性配置及IOC容器 Transcational annotation標(biāo)注的事務(wù)管

29、理功能 集成測(cè)試的基類3.1 IOC部分特征使用 詳見(jiàn)Spring 筆記(江南白衣博物館) 3.1.1 零配置文件的使用場(chǎng)合 Service,Dao 層在無(wú)特殊配置項(xiàng)時(shí),可使用IOC Annotation進(jìn)行配置 實(shí)現(xiàn)約定俗成大于配置的零配置文件. 而其他Database/SessionFactory ,SpringSecurity, CXF等需要進(jìn)行參數(shù)配置時(shí),仍然使用 XML 配置文件。 3.1.2 零配置文件的annotation SpringSide3中使用Component注釋所有類別,在setter方法(不需要嚴(yán)格按setter命名)上 使用Autowired 進(jìn)行byType注入

30、,如果需要byName注入則使用Resource。 3.1.3 其他特征 使用Required注釋沒(méi)有用Autowired注釋的屬性,保證對(duì)象必然被注入,如果對(duì)象沒(méi)有被注入則報(bào)錯(cuò)。 使用JSR250的PostConstruct來(lái)定義在執(zhí)行完所有setter注入后必須執(zhí)行的函數(shù)。PreDestroy來(lái)定義JDK關(guān)閉時(shí)通過(guò) shutdownhook調(diào)用的函數(shù)。 ApplcationContext中默認(rèn)設(shè)置Lazyload 與Autowired by type 仍然是必然的選擇。 3.1.4 屬性文件管理 在配置文件中,很有一些屬性會(huì)在團(tuán)隊(duì)的開(kāi)發(fā)環(huán)境,個(gè)人的開(kāi)發(fā)環(huán)境,集成測(cè)試環(huán)境,以及生產(chǎn)環(huán)境集群的

31、每臺(tái)服務(wù)器中都有所不同的。詳見(jiàn)Spring 筆記(江南白衣博物館)3.2 事務(wù)管理 在Service層用Transactional 定義事務(wù),詳見(jiàn)Spring 筆記(江南白衣博物館)。 注意Spring3.0 的Transactional終于支持多個(gè)TransactionManager了, showcase里演示了多個(gè)數(shù)據(jù)源(不要求聯(lián)合事務(wù)JTA)導(dǎo)致多個(gè)TransactionManager的情況。此時(shí)Transactional默 認(rèn)使用中指定的TransactionManager, 但也可以重新指定其他的TransactionManager的BeanName. 在AOP不到的地方,仍然有機(jī)會(huì)

32、使用TransactionTemplate,(見(jiàn)Showcase的UserJdbcDao 與 LogJdbcWriter。)3.3 集成測(cè)試的基類 詳見(jiàn) 測(cè)試文檔4. in SpringSide34.1 Showcase中使用的Spring功能索引 JMX:JMX的Server端封裝 JMS:JMS Template封裝 Email:EMail客戶端封裝 Schedule:Quartz的封裝,ScheduleExecutor的封裝 Ehcache:Ehcache Server封裝 Jdbc:Spring JdbcTemplate4.2 SpringContextHolder 在Spring A

33、pplicationContext啟動(dòng)時(shí),先把Context放入個(gè)該類的靜態(tài)變量,當(dāng)模塊的代碼無(wú)法通過(guò)正常渠道獲得Spring Context及其中的Bean時(shí),可直接從該靜態(tài)變量中獲取。4.3 AOP Aspect的寫(xiě)法 最新的寫(xiě)法,一切都寫(xiě)在java文件里,只要在applicationContext.xml里面定義一把scan就可以了。 詳見(jiàn)showcase中的TraceLogAspect。 Database: ORM-Hibernate, Jdbc-Spring JdbcTemplate, 數(shù)據(jù)庫(kù) - H2、MySQL、Oracle, 數(shù)據(jù)庫(kù)連接池-DBCP1. 資料 數(shù)據(jù)庫(kù)訪問(wèn)資料(江

34、南白衣博物館) JPA與Hibernate筆記(江南白衣博物館)2. 選型 因?yàn)樽罱荒陙?lái),JPA與EJB3的應(yīng)用都沒(méi)有想象中的多,在國(guó)內(nèi)尤其突出。所以仍然使用純Hibernate API+JPA1.0 annotation. 支持JPA2.0的Hibernate 3.5剛出來(lái),要再繼續(xù)觀察。3. in SpringSide 33.1 Entity類 1.Mini-Web中的User類是entity類的典型,集中演示了緩存,默認(rèn)命名策略,多對(duì)多關(guān)系的定義和fetch策略,級(jí)聯(lián)操作策略,子集合的 排序和緩存、非持久化屬性, 見(jiàn)JPA與Hibernate筆記 2.為了統(tǒng)一ID的列名與生成算法,編寫(xiě)

35、了IdEntity基類,演示了自增序列,數(shù)據(jù)庫(kù)Sequence(Oracle), UUID(多數(shù)據(jù)庫(kù))的情形。(如果要在Oracle中為每個(gè)Entity對(duì)應(yīng)不同Sequence時(shí)- 重載getId()函數(shù))。3.2 更換MySQL或Oralce等數(shù)據(jù)庫(kù)詳見(jiàn)數(shù)據(jù)庫(kù)說(shuō)明。1. H21.1 選型 H2嵌入式模式是功能測(cè)試的首選。測(cè)試要求數(shù)據(jù)庫(kù)運(yùn)行要非??焖伲覟槊鉁y(cè)試間數(shù)據(jù)的耦合,要能在每個(gè)測(cè)試間很快速的重建數(shù)據(jù),H2剛好滿足這個(gè)需求。 H2的主要對(duì)手是Derby,對(duì)比顯示H2比Derby更快,而且有著非常好用的Web管理界面(在Web界面里寫(xiě)SQL時(shí)居然有表名列名的動(dòng)態(tài)提示.)1.2 in Sp

36、ringside 3 在/tools/h2目錄里帶了啟動(dòng)H2的命令(借助于maven管理的Jar包)。 另外,H2完全兼容hsqldb的語(yǔ)法,一般依賴數(shù)據(jù)庫(kù)的開(kāi)源項(xiàng)目都附帶有hsqldb語(yǔ)法的初始化腳本。 SpringSide3中在使用嵌入式H2提供快速功能測(cè)試。url為jdbc:h2:mem:mini-service;DB_CLOSE_DELAY=-1 同時(shí)運(yùn)行期的數(shù)據(jù)庫(kù)也使用了H2的Server模式,url為jdbc:h2:tcp:/localhost/mini-service。2. MySQL 與 Oracle 開(kāi)發(fā)實(shí)際項(xiàng)目時(shí),需要將H2更換為實(shí)際數(shù)據(jù)庫(kù),Hibernate支持大部分的數(shù)

37、據(jù)庫(kù),其中Java程序員選用MySQL和Oracle的最多。 更換MySQL與Oracle 主要修改幾個(gè)地方,SpringSide已在兩個(gè)mini-example中帶了示范配置,取消相應(yīng)的注釋符號(hào)即可。1.pom.xml一節(jié)jar包的groupid與artifactId,version用于下載依賴包。注意因?yàn)榘鏅?quán)問(wèn)題,Oracle的Driver不在maven官網(wǎng)的倉(cāng)庫(kù)上,需要自行發(fā)布到團(tuán)隊(duì)的私服或拷貝到本機(jī)的maven倉(cāng)庫(kù)目錄。2.src/main/resource/perties用于連接池與hibernate的配置。3. bin/build.xml用于導(dǎo)出導(dǎo)入

38、數(shù)據(jù)到數(shù)據(jù)庫(kù)。4. bin/hibernate/hibernate.cfg.xml如果需要用hibernate-tools生成代碼則修改此文件,否則可忽略。5.修改entity的ID生成策略。 注意Oracle中一般會(huì)為每個(gè)主要的表創(chuàng)建一個(gè)Sequence,所以繼承于IdEntity的子類需要重載getId()方法指定Sequence名。 當(dāng)然也可以只修改IdEntity基類,所有entity共用一個(gè)sequence。3.3 Event機(jī)制 在Showcase中的AuditListener, 演示了利用Event機(jī)制,在save與update時(shí)自動(dòng)為實(shí)體加入審計(jì)信息(創(chuàng)建人與創(chuàng)建時(shí)間,最后修改

39、人與修改時(shí)間)3.4 Version字段 在Showcase中演示,Version字段用在諸如兩個(gè)管理員在差不多時(shí)間里打開(kāi)了同一對(duì)象的修改頁(yè)面可能引發(fā)的沖突,Struts2的 Prepareable機(jī)制對(duì)其使用有些許影響,需進(jìn)行編碼檢查, 詳見(jiàn)UserAction.3.5 Clob字段 在Showcase中演示,Clob字段用String表示即可,但為了達(dá)到Lazy Load的效果,必需進(jìn)行byte code enhancement,見(jiàn)showcase中bin/hibernate/bytecode-instrument中執(zhí)行的Ant指令。LobBasic(fetch = FetchType.L

40、AZY)public String getContent() return content;3.6 繼承 在Showcase中演示,為性能考慮,一般采用同表繼承,另外,在基類放一個(gè)ForceDiscriminator有時(shí)候很有用。Table(name = SS_POST)Inheritance(strategy = InheritanceType.SINGLE_TABLE)ForceDiscriminatorpublic abstract class PostEntityDiscriminatorValue(Subject)public class Subject extends Post 3

41、.7自定義ID生成器 在Showcase中演示一個(gè)16位的UID生成。3.8 關(guān)聯(lián)關(guān)系大全 在mini-web中演示ManyToMany. 在shwocase中演示,單向,雙向的OneToMany, ManyToOne .4. in SpringSide II -性能相關(guān) Hibernate 其實(shí)做了很多性能相關(guān)的優(yōu)化,大家可以盡量使用后,再?zèng)Q定要不要直接跑JDBC。4.1 二級(jí)緩存 在Entity類及其Collection屬性中都可以聲明Hibernate緩存策略。Entity緩存對(duì)象實(shí)體,而Collection則緩存對(duì)象間 的關(guān)系。 注意并不是所有對(duì)象都適合緩存,需要進(jìn)行精心選擇,詳見(jiàn) H

42、ibernate筆記。 這里使用了ehcache cache方案, 支持基于JGroups分布式二級(jí)緩存,在sessionFactory處配置了ehcache_hibernate.xml的配置文件。關(guān)于 Ehcache詳見(jiàn)Ehcache部分。 QueryCache本身就是吃力不討好的事情,在集群環(huán)境下更加需要注意,因此我們一般不推薦使用使用查詢緩存.4.2 不使用OpenSessionInFilter 對(duì)于性能要求較高的Web網(wǎng)站與WebService應(yīng)用,還是應(yīng)該在Service層用Hibernate.init()主動(dòng)初始化對(duì)象然后關(guān)閉 Session。詳見(jiàn)mini-service的演示。注

43、意Hibernate.init(user)初始化user對(duì)象,而如果要同時(shí)初始化user與 user的Lob字段與關(guān)聯(lián)對(duì)象,調(diào)用的是Hibernate.init(user.getRoles(), Hibernate.init(user.getDescription().4.3 預(yù)Fecth關(guān)聯(lián)對(duì)象集合 HQL與Criteria都可以一次關(guān)聯(lián)查詢查出主對(duì)象與關(guān)聯(lián)對(duì)象集合,需要注意的查出來(lái)的記錄和我們平時(shí)用jdbc查一樣,有三個(gè)子對(duì)象就會(huì)有三條重復(fù) 的主對(duì)象記錄,可以用CriteriaSpecification.DISTINCT_ROOT_ENTITY去除重復(fù)。 注意,如果關(guān)聯(lián)對(duì)象集合和關(guān)聯(lián)對(duì)象是

44、被緩存的,就不一定要預(yù)Fetch對(duì)象了。 詳見(jiàn)Showcase的UserDaoTest 。4.3 Bulk Update HQL 嗯,HQL也有Update/Delete語(yǔ)句的, 詳見(jiàn)Showcase的UserDaoTest 。4.4 擴(kuò)展HQL Dialect 如果有些數(shù)據(jù)庫(kù)特定的功能而Hibernate又還沒(méi)提供的話,可以簡(jiǎn)單的擴(kuò)展HQL Dialect. Showcase中的H2ExtDialect,為H2Dialect添加了兩個(gè)新函數(shù), 測(cè)試函數(shù)見(jiàn)UserDaoTest。4.5 直接JDBC訪問(wèn) 如果還是不行,就在需要的地方干脆的使用JdbcTemplate吧,不要折騰什么Hibern

45、ate Native SQL了。5. SpringSide3 封裝5.1 DAO類 1.通用的HibernateDAO SpringSide 3 封裝的泛型SimpleHibernateDAO與HibernateDAO類,前者具有通用的CRUD函 數(shù),QBH,QBC函數(shù),后者擴(kuò)展了SpringSide的分頁(yè)查詢函數(shù)以及按屬性過(guò)濾條件的查詢函數(shù)。 因?yàn)镠ibernateDAO已滿足一般的DAO需要,因此可以直接在Service層中直接使用,仍然定義DAO子類主要為了保存注入 sessionFactory對(duì)象(否則sessionFactory要注入到Service層) 以及 可能存在的特殊DAO操

46、作。 這里指的特殊處理并不是指一條HQL查詢或一個(gè)按屬性的查詢都封裝出一個(gè)查詢函數(shù),而是指RoleDAO中級(jí)聯(lián)刪除中間表這種真正特殊的 hibernate API調(diào)用和操作。 2. 不繼承于HibernateDaoSupport/HibernateTemplate 參考Spring最新的Petlinc例子,DAO不再繼承于Spring復(fù)雜的HibernateDaoSupport(Spring 1.x+ Hibernate 2.xd的產(chǎn)物),而是直接使用H3推薦的sessionFactorygetCurrentSession()方法與Hibernate的原生 API。5.2 分頁(yè)查詢 Sprin

47、gSide3封裝的Page類配合Hibernate query by Criteria,可以迎合展示層Grid(表格控件)的種種需求(分頁(yè),排序,按屬性查找)。 Page類分兩部分: 一部分是請(qǐng)求參數(shù):pageSize、pageNo、orderBy(多個(gè)排序字段以,分隔)、asc(是否升序,多個(gè)排序字段以,分隔)、 autoCount(是否自動(dòng)執(zhí)行count查詢統(tǒng)計(jì)總結(jié)果數(shù)) 。 一部分是查詢結(jié)果:result(分頁(yè)的結(jié)果List),totalCount(查詢的總結(jié)果數(shù)),totalPages(總頁(yè)數(shù)), 以及相應(yīng)的上頁(yè)頁(yè)號(hào),下頁(yè)頁(yè)號(hào),是否還有上一頁(yè),是否還有下一頁(yè)等函數(shù)。 請(qǐng)求參數(shù)與結(jié)果放在

48、同一個(gè)類里,是因?yàn)楹芏鄷r(shí)候參數(shù)需要帶到結(jié)果里,在頁(yè)面上流轉(zhuǎn)下去。 在queryByHQL的情況下,對(duì)簡(jiǎn)單HQL能夠自動(dòng)查詢,而復(fù)雜的時(shí)候就需要自己另行執(zhí)行count HQL語(yǔ)句查詢后設(shè)置totalPages。5.3 屬性過(guò)濾條件 SpringSide封裝的PropertyFitler類,可在頁(yè)面中簡(jiǎn)單定義filter_EQS_name, filter_LIKES_NAME_OR_LOGIN_NAME的請(qǐng)求參數(shù),可通過(guò)HibernateWebUtils的 buildPropertyFilter(ServletRequest)函數(shù)快速構(gòu)造出PropertiyFilter列表并傳遞到 Hiberna

49、teDAO的search(List)函數(shù)中,整個(gè)過(guò)程非常自動(dòng)化,無(wú)需太多的特定編 碼,filter的命名規(guī)則也一目了然。其中比較類型可選 EQ, LIKE, LT, GT, LE, GE;比較值類型可選S(String.class), I(Integer.class), L(Long.class), N(Double.class), D(Date.class), B(Boolean.class);如果要同時(shí)比較多個(gè)屬性,屬性名之間用_OR_分隔.5.4 HibernateUtils 像用戶與角色,訂單與訂單項(xiàng)這些關(guān)聯(lián)關(guān)系,通常需要展現(xiàn)到頁(yè)面上的checkbox list 中,經(jīng)用戶重新勾勾選后

50、,再保存回?cái)?shù)據(jù)庫(kù)。HibernateWebUtils提供了合并原有關(guān)聯(lián)對(duì)象集合與勾選結(jié)果的Utils函數(shù)。 另外一個(gè)重要的函數(shù)是將頁(yè)面上傳來(lái)的filter_XXX參數(shù)構(gòu)造成屬性過(guò)濾條件列表。Overview 無(wú)論Hibernate多么好,有時(shí)候還是需要直接的Jdbc訪問(wèn)。Spring的Jdbc Template提供了幾個(gè)簡(jiǎn)單但實(shí)用的功能: 數(shù)據(jù)源,連接與事務(wù)的管理 命名查詢參數(shù)的快速綁定(Map/Bean形式)。 查詢結(jié)果的快速轉(zhuǎn)換與組裝。 在Showcase的UserJdbcDao中,對(duì)JdbcTemplate的功能逐一做了演示,包括: 查詢單個(gè)對(duì)象/對(duì)象列表(用RowMapper轉(zhuǎn)換業(yè)務(wù)對(duì)

51、象) 查詢單個(gè)結(jié)果Map /Map列表(類似ResultSet) 使用Map形式傳入的命名參數(shù) 使用Bean形式傳入的命名參數(shù) 特別演示了IN語(yǔ)句的命名參數(shù)使用, where id in (:ids), 輸入一個(gè)List參數(shù)即可。 批處理更新。 使用SQL Builder,在XML文件里定義Freemarker SQL模板。TransactionTemplate 有時(shí)會(huì)嫌方法級(jí)別的Transactional太粗曠,還是想自己精確控制事務(wù),就用TransactionTemplate了, 在Showcase的UserJdbcDao演示了有/無(wú)返回值的事務(wù)以及需要catch異常自行處理不想再拋出的情

52、形。 另外一個(gè)典型的場(chǎng)景是應(yīng)用更改數(shù)據(jù)庫(kù)后發(fā)送JMS消息,為了使消息接收者能查詢到最新的數(shù)據(jù),最好用TrasactionTemplate來(lái)精確控制事務(wù) 提交。SQL Builder SQLBuilder支持Velocity來(lái)渲染定義在XML中的SQL. 為什么要用模板好處有二: 1.相比只能用+號(hào)換行而且老被Eclipse自動(dòng)格式化的Java 字符串,XML中可以自由的縮進(jìn)與換行。 2.可以用Velocity來(lái)自由動(dòng)態(tài)的拼裝SQL, 這個(gè)好處更無(wú)需多言了。 為什么不選用Freemarker做模板引擎,原因同樣有二:1. 因?yàn)镾QL定義在spring的applicationContext-*.x

53、ml中,freemarker的變量定義與Spring的 placeholder一樣,會(huì)引起沖突.2. Velocity最近居然比Freemarker活躍. 詳見(jiàn)Showcase的UserJdbcDao及其測(cè)試用例。1. H21.1 選型 H2嵌入式模式是功能測(cè)試的首選。測(cè)試要求數(shù)據(jù)庫(kù)運(yùn)行要非??焖?,而且為免測(cè)試間數(shù)據(jù)的耦合,要能在每個(gè)測(cè)試間很快速的重建數(shù)據(jù),H2剛好滿足這個(gè)需求。 H2的主要對(duì)手是Derby,對(duì)比顯示H2比Derby更快,而且有著非常好用的Web管理界面(在Web界面里寫(xiě)SQL時(shí)居然有表名列名的動(dòng)態(tài)提 示.)1.2 in Springside 3 在/tools/h2目錄里帶了啟動(dòng)H2的命令(借助于maven管理的Jar包)。 另外,H2完全兼容hsqldb的語(yǔ)法,一般依賴數(shù)據(jù)庫(kù)的開(kāi)源項(xiàng)目都附帶有hsqldb語(yǔ)法的初始化腳本。 SpringSide3中在使用嵌入式H2提供快速功能測(cè)試。url為jdbc:h2:mem:mini- service;DB_CLOSE_DELAY=-1 同時(shí)運(yùn)行期的數(shù)據(jù)庫(kù)也使用了H2的Server模式,url為jdbc:h2:tcp:/localhost/mini-service。2. MySQL 與 Oracle 開(kāi)發(fā)實(shí)際項(xiàng)目時(shí),需要將H2更

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論