【文章內(nèi)容簡(jiǎn)介】
關(guān)閉SessionResponseResponseRequestRequest Hibernate過濾器在Web容器啟動(dòng)時(shí),過濾器被初始化,它將執(zhí)行init()方法,在后續(xù)的操作中不會(huì)再次被執(zhí)行;而當(dāng)容器關(guān)閉時(shí),過濾器將執(zhí)行destroy()方法。這兩個(gè)方法恰好符合SessionFactory對(duì)象的生命周期,在運(yùn)行期間只執(zhí)行一次操作,可用于實(shí)例化及銷毀SessionFactory對(duì)象。對(duì)于Session對(duì)象的關(guān)閉操作,可以在業(yè)務(wù)邏輯處理結(jié)束后、response請(qǐng)求轉(zhuǎn)發(fā)大View層之前進(jìn)行。實(shí)例將其封裝在HibernateFilter類中,此類繼承了Filter類,它是一個(gè)過濾器。為了保證線程的安全性,實(shí)例中將Session對(duì)象存放與ThreadLocal對(duì)象中,當(dāng)用到一個(gè)Session對(duì)象時(shí),首先從ThreadLocal中獲取,在無法獲取的情況下才會(huì)開啟一個(gè)新的Session對(duì)象。同時(shí),為了保證Session對(duì)象能在resopnse請(qǐng)求轉(zhuǎn)發(fā)到View層之前被關(guān)閉,實(shí)例采取了try…finally語句對(duì)Session對(duì)象進(jìn)行關(guān)閉。 SupperDao類SupperDao類為項(xiàng)目中所有數(shù)據(jù)庫操作類的父類,此類封裝了數(shù)據(jù)庫操作的常用方法。在此類中,由于Hibernate對(duì)數(shù)據(jù)的操作都需要用到Session接口,類中定義了一個(gè)protected類型的Session對(duì)象,為其子類提供了方便。save()方法及savaOrUpdate()方法都用于保存一個(gè)對(duì)象,其入口參數(shù)均為Object類型。其中saveOrUpdate()方法比save()方法更智能一些,可以根據(jù)實(shí)體對(duì)象中的標(biāo)識(shí)值來判斷保存還是更新操作。SupperDao類中使用這兩個(gè)方法對(duì)實(shí)體對(duì)象進(jìn)行保存及更新操作。刪除操作的方法為delete(),入口參數(shù)為Object類型,此方法通過Session接口的delete()方法進(jìn)行實(shí)現(xiàn)。SupperDao類為項(xiàng)目中所有數(shù)據(jù)庫操作類的父類,在設(shè)計(jì)時(shí)應(yīng)當(dāng)考慮全面。Hibernate的HQL查詢語言提供了更為靈活的查詢方式,在這個(gè)超類之中應(yīng)該加入HQL的操作方法,其中findByHQL()方法用于根據(jù)指定的HQL查詢語句查詢結(jié)果集,deleteByHQL()方法用于根據(jù)指定的HQL查詢語句進(jìn)行刪除操作。Hibernate單值檢索在查詢后返回單個(gè)對(duì)象,當(dāng)返回的結(jié)果包含多條數(shù)據(jù)時(shí),Hibernate將拋出異常。此種操作可用于查詢單條數(shù)據(jù),如聚合函數(shù)count()等。在SupperDao類中,單值檢索的方法為uniqueResult()。此方法的入口參數(shù)為HQL查詢語句及查詢條件,其中查詢條件為Object[]數(shù)組類型,用于裝載查詢語句中的參數(shù)。例如HQL語句“from Medicine m where =?”,此時(shí)即可通過參數(shù)where對(duì)其進(jìn)行動(dòng)態(tài)賦值。分頁查詢?cè)诔绦蜷_發(fā)中經(jīng)常用到,不但方便查看,還可以減少結(jié)果集的返回?cái)?shù)量,提高數(shù)據(jù)訪問效率。使用Hibernate的分頁查詢方法極為簡(jiǎn)單,只需要傳入幾個(gè)參數(shù)即可,但在SupperDao類中對(duì)其進(jìn)行了擴(kuò)展,加入了HQL語句的動(dòng)態(tài)賦值,其方法名為findPaging()。此方法入口參數(shù)有4個(gè),其中參數(shù)hql為HQL查詢語句,它允許傳入?yún)?shù)中帶有占位符“?”的HQL語句;參數(shù)offset為查詢結(jié)果集對(duì)象的起始位置;參數(shù)length為查詢結(jié)果的偏移量,也是返回?cái)?shù)據(jù)的條目數(shù);參數(shù)where為查詢條件,屬于Object[]數(shù)組類型,用于裝載HQL語句中的參數(shù)。通過上述這幾個(gè)參數(shù)基本可以滿足項(xiàng)目中所有的分頁查詢,當(dāng)然遇到特殊情況時(shí),可以通過子類對(duì)象重寫此方法。 BaseAction類BaseAction類是業(yè)務(wù)層,有一個(gè)超類對(duì)象,它繼承了Struts的DispatchAction類,同時(shí)還為子類對(duì)象提供公用方法。此類首先定義了3個(gè)protected類型的變量,分別用于設(shè)置每頁的記錄數(shù)、本地語言信息及國(guó)際化消息資源。Struts的DispatchAction類繼承了Action類,此類處理請(qǐng)求時(shí)首先要執(zhí)行execute()方法,然后通過控制器再轉(zhuǎn)發(fā)到相應(yīng)的方法進(jìn)行業(yè)務(wù)處理。根據(jù)這一分析,可以在execute()方法中對(duì)用戶的身份作出驗(yàn)證。業(yè)務(wù)請(qǐng)求一業(yè)務(wù)請(qǐng)求三業(yè)務(wù)請(qǐng)求二業(yè)務(wù)請(qǐng)求四業(yè)務(wù)處理二業(yè)務(wù)處理三業(yè)務(wù)處理一業(yè)務(wù)處理四Execute()方法驗(yàn)證用戶身份錯(cuò)誤處理驗(yàn)證失敗驗(yàn)證成功驗(yàn)證成功 用戶身份驗(yàn)證如果對(duì)系統(tǒng)中涉及到的Action均編寫一個(gè)驗(yàn)證方法,則程序代碼的重復(fù)性太高,不能體現(xiàn)出面向?qū)ο蟮脑O(shè)計(jì)模式,所以需將其單獨(dú)封裝在BaseAction類中,此類通過重寫Action類的execute()方法對(duì)用戶身份進(jìn)行驗(yàn)證。由于分頁查詢的應(yīng)用比較多,所以在業(yè)務(wù)層將其封裝在BaseAction類中,通過getPage()方法進(jìn)行實(shí)現(xiàn),子類對(duì)象可以通過繼承來獲取此方法。getPage()方法返回一個(gè)Map集合對(duì)象,該集合用于裝載結(jié)果集及分頁條。其中,結(jié)果集對(duì)象為一頁中的所有數(shù)據(jù)集合,它是一個(gè)List對(duì)象;分頁條為分頁查詢后在JSP頁面所顯示的分頁信息,如記錄數(shù)、頁碼、上一頁、下一頁的超鏈接等,它是一個(gè)String類型的字符串。 getPage()方法的入口參數(shù)有四個(gè),其中參數(shù)hql為分頁查詢的HQL語句,此語句不可以包括select子句,它從from子句開始,可以傳入帶有占位符的HQL,但需要通過查詢條件參數(shù)where傳遞占位符的值,當(dāng)HQL語句沒有參數(shù)時(shí),where參數(shù)可以設(shè)置為null;參數(shù)recPerPage為每一頁的記錄數(shù);currPage為當(dāng)前的頁碼;action為分頁所請(qǐng)求的Action地址。getPage()方法提供這些參數(shù)的目的在于提高程序代碼的重用性,因?yàn)樵卺t(yī)藥銷售管理系統(tǒng)中,通過這些參數(shù),getPage()方法已滿足所有的分頁查詢,用到分頁查詢的地方都調(diào)用了此方法。此外,在其他項(xiàng)目中此方法的重用價(jià)值也是非常高的。分頁查詢?cè)跇I(yè)務(wù)層的實(shí)現(xiàn)比較繁瑣,因?yàn)樵诜猪摋l中要考慮到國(guó)際化的實(shí)現(xiàn),所以在分頁條中所有文字信息均通過MessageResources對(duì)象讀取國(guó)際化資源文件來獲取。MessageResources對(duì)象是Struts中的對(duì)象,此對(duì)象根據(jù)Locale信息讀取相應(yīng)的國(guó)際化消息資源文件。 DeleteAction類公共類DeleteAction主要用于對(duì)項(xiàng)目中LookupDispatchAction的請(qǐng)求進(jìn)行處理。它繼承了LookupDispatchAction類,重寫了execute()方法對(duì)用戶的身份作出驗(yàn)證,當(dāng)用戶身份驗(yàn)證失敗時(shí)將進(jìn)行錯(cuò)誤處理;同時(shí),此類還重寫了LookupDispatchAction類中的getKeyMethodMap()方法,添加了兩個(gè)按鈕對(duì)象的key。 字符串工具類在一個(gè)Web項(xiàng)目中,字符串是經(jīng)常被操作的對(duì)象。為了簡(jiǎn)化程序的代碼及提高程序的可讀性,對(duì)于經(jīng)常用到的字符串處理方法,可以封裝一個(gè)字符串工具類對(duì)其進(jìn)行操作。例如JSP頁面的多選框,它提交的參數(shù)值為數(shù)組類型,在數(shù)據(jù)庫的操作過程中需要將其轉(zhuǎn)換為字符串類型;在超鏈接中,如果加入中文參數(shù)將不能被瀏覽器解析,需要對(duì)其進(jìn)行一定的處理才可以使用。類似于這種操作在程序中使用的非常頻繁,將其封裝為一個(gè)公共類無疑是一種較好的解決方案。在醫(yī)藥銷售管理系統(tǒng)中,封裝了一個(gè)名為StringUtil的字符串工具類,用于對(duì)字符的特殊處理。此類中均為靜態(tài)方法。在HQL語句中,如果刪除多個(gè)對(duì)象可以使用where id in(1,2,3)的方式進(jìn)行刪除。arr2Str()方法用于將數(shù)組轉(zhuǎn)換為字符串,可以將JSP表單傳遞id值轉(zhuǎn)換為此種方式;encodeURL()方法可對(duì)字符串進(jìn)行URL編碼,主要用于對(duì)含有中文的超鏈接進(jìn)行處理;encodeZh()方法用于對(duì)字符串中的中文亂碼進(jìn)行處理。7 國(guó)際化國(guó)際化是Struts的一項(xiàng)強(qiáng)大功能,它以不同國(guó)家的語言構(gòu)建本地化的頁面,方便不同國(guó)家、不同語言的用戶瀏覽訪問。在醫(yī)藥銷售管理系統(tǒng)中,分別構(gòu)建了中文和英文兩種語言環(huán)境,根據(jù)使用者瀏覽器的默認(rèn)語言環(huán)境呈現(xiàn)不同的語言顯示方式。 國(guó)際化資源文件醫(yī)藥銷售管理系統(tǒng)對(duì)所有涉及到語言信息的地方均進(jìn)行了國(guó)際化設(shè)置,包括JSP頁面文字信息及JS腳本提示信息等。主要包含3個(gè)國(guó)際化資源文件,實(shí)例中將其設(shè)置為中文;;。在編寫屬性文件時(shí)應(yīng)該注意,屬性文件以Unicode編碼,在處理中文時(shí)應(yīng)該對(duì)其進(jìn)行轉(zhuǎn)碼。Java提供了將中文轉(zhuǎn)換為Unicode編碼格式的工具,在命令窗口中直接輸入“native2ascii”,再輸入中文,然后按回車鍵,將輸出中文對(duì)應(yīng)的Unicode碼。 國(guó)際化實(shí)現(xiàn)實(shí)例中除了對(duì)用戶瀏覽器語言的自動(dòng)匹配外,還為使用者提供了中文和英文的語言鏈接,用戶在使用過程中可對(duì)語言進(jìn)行自動(dòng)切換。此請(qǐng)求由LanguageAction類進(jìn)行處理。,它是Struts的默認(rèn)配置,可以通過Strtus的API幫助文檔和源碼得到。對(duì)于中、英文兩種請(qǐng)求,實(shí)例中分別創(chuàng)建了中、英文所對(duì)應(yīng)的Locale對(duì)象,實(shí)現(xiàn)了語言的自動(dòng)切換。8 系統(tǒng)登陸模塊系統(tǒng)登錄是一個(gè)用戶身份驗(yàn)證的過程,只有登錄成功的用戶才可以對(duì)系統(tǒng)進(jìn)行操作,否則不能對(duì)系統(tǒng)進(jìn)行管理維護(hù)。形象地說,它就是系統(tǒng)的一道安全門。 查詢用戶創(chuàng)建名為UserDao的類,封裝對(duì)用戶及系統(tǒng)級(jí)的數(shù)據(jù)操作。在此類中編寫login()方法,用于根據(jù)用戶