Struts+Spring+Hibernate開發執行個體
來源:互聯網
上載者:User
一 本文並不想介紹Struts,Spring,Hibernate的原理系統架構等,本文地目的是通過一個較複雜地執行個體介紹如何整合Struts,Spring,Hibernate,網上現有的例子雖然也能達到目的,但功能都比較單一,複雜的例子時會有意想不到的麻煩。本文對讀者假設已經具備了以上架構的基礎知識。以及那些已經瞭解Struts,Spring,Hibernate的基本概念,但是還沒有親身在較複雜的項目中體驗Struts+Spring+Hibernate的開發人員。 1
Struts 雖然不打算過多介紹Struts的原理,但是大概介紹一下還是有必要的。Struts本身就是 MVC 在這裡負責將使用者資料傳人業務層,以及 將業務層處理的結果返回給使用者,此系統屬於較簡單WEB應用,採用了OpenSessionInView模式處理LazyLoad問題,這樣我們可以在使用者視圖中使用 get,set方法來方便地擷取關聯對象。為了處理龐大的Action和ActionForm問題,在此我門準備使用DynaActionForm (DynaValidatorForm)和DispatchAction以及 動態驗證架構 來解決。及使用Tile來解決架構問題 。使用自訂標籤處理分頁和身分識別驗證問題。
2 Spring Spring Framework最得以出名的是與Hibernate的無縫連結,雖然Spring 對Hibernate提供了90%以上的封裝,使我們不必去關心Session 的建立,關閉,以及事務使我們能夠專心的關注商務邏輯。但是一些特殊情況如 有時需要Query以及Criteria 對象,分頁等,Spring不能給我們提供支援,總不能每次都在你的DAO上寫個 HibernateCallBackup() 吧。 Spring 的作用不是把 Hibernate 再封裝一層,而是讓你接觸不到 Hibernate 的 API ,而是協助你管理好 Session 和 Transaction 。 在這裡解決方案是:首先 寫一個 IBase 的介面,和一個 BaseDao 的實現。在實現中仿照HibernateTemplate,將其功能一一實現,同時考慮到Spring 未能支援的地方,我們不得已只好自己來管理 Session,因此加入public Session openSession(),public Query getQuery(String sql),public Criteria getCriteria(Class clazz),以及分頁的方法。 然後為每一個Entity 都建立繼承於以上類的IEntity,與EntityDao。這裡可以根據需求對Entity加入特殊的方法實現,如 在 StudentsDao.java 中加入類似使用者身分識別驗證等。以上就是資料訪問層。接下來在Service層中通過對dao的引用完成商務邏輯方法。在下面的例子中我們分別為學生模組,教師模組,管理員模組構建Service層,StudentsServiceImpl,TeachersServiceImpl,AdminServiceImpl。
3 Hibernate 有了Spring的封裝,我們要對Hibernate做的就是正確實現對象關係的映射。由於此處處於系統的最底層,準確無誤的實現對象之間的關聯關係映射將起著至關重要的作用。 總之,理解了Struts,Spring,Hibernate地原理以及之間的關係之後,剩下的工作就如同在以Spring為核心的Struts為表現的架構中 堆積木。 下圖可以更好的協助我們理解Struts,Spring,Hibernate之間的關係。
二
案例簡述: 設計思路主要源於 大學選修課,該系統可以方便處理學生在課程選報,學分查詢,成績查詢,以及 成績發布等。 系統以班級為核心,一門課程可以對應多個班級,一名教師也可以帶不同的班級,學生可以選報不同課程所對應的班級,班級自身有目前人數,和最大人數,以及上課時間,上課地點的屬性。 學生在選報班級之後,班級的人數會自動加一,直到等於最大人數時,其他學生將會有人數已滿的錯誤提示。同理如果學生選擇了同一課程的不同班級,也將收到錯誤提示。學生有密碼,系別,學分,地址,電話等屬性。 教師在系統中主要負責成績發布,教師可以對其所帶的班級的學生的成績修改,系統會以成績是否大於等於60來判斷學生是否通過考試,如果通過會將該課程的學分累加到學生學分,同樣如果教師二次修改了成績,而且小於60,系統會在學生學分上扣掉該課程的分數。 課程在系統中具體體現為班級,自身帶有學分屬性。
系有編號,名稱的屬性,同時可以作為聯絡教師,課程,學生的橋樑。
功能模組 l 身分識別驗證模組: 根據使用者名稱,密碼,使用者類別 轉寄使用者到不同的模組。 l 學生模組: 查看課程,查看班級,選報課程,查看己選課程,成績查詢。 l 教師模組: 錄入成績 l 管理員模組:對學生,教師,課程,班級,系 增,刪,查,改。
三
具體實踐
代碼下載
http://www.blogjava.net/Files/limq/StudentManger.rar
1
對象關係映射: 首先,將庫表映射為資料模型(SQL 在源碼中查看),轉換後的資料模型如下圖:
由此我們可以看出一下關聯關係: 1 Students 和 Contact(連絡方式)一對一關聯性。 2 Students 和 History(選課曆史) 一對多關聯性 3 Students 和 Classes 多對多關係。 4 Classes 和 Classes_info 一對多關聯性。 5 Classes 和 Teachers 多對一關聯性。 6 Classes 和 Courses 多對一關聯性。 7 Course 和 Department(系) 多對一關聯性。 8 Teachers 和 Department 多對一關聯性。 9 Students 和 Department 多對一關聯性。 在Hibernate中將以上關係一一映射,如Students 和 History 一對多關聯性 Students.cfg.xm.: 1 < set name ="history"
2 table ="history"
3 cascade ="all"
4 inverse ="true"
5 lazy ="true" >
6 < key column ="student_id" />
7 < one-to-many class ="limq.hibernate.vo.History"
8 />
9 set>
10 用過MyEclipse開發Hibernate的就知道,MyEclipse會協助我們產生持久對象和抽象對象,我們要在 Students.java 中加入對History的引用 private Set history=new HashSet(); public Set getHistory() { return history; } public void setHistory(Set history) { this.history = history; } 同時,在AbstractHistory.java 中刪除student_id 以及對應的get,set 方法,History.java 中加入 private Students student; public Students getStudent() { return student; } public void setStudent(Students student) { this.student = student; } 具體內容請查看 原始碼。
1 public interface IDepartment extends IBaseDao {}
2
3 public class DepartmentDao extends BaseDao implements IBaseDao {}
4
3 Service
層 在這裡需要認真思考每個商務邏輯所能用到的持久層對象和DAO,還要完成配置Spring架構, 首先我一起看看applications-service.xml
1 xml version="1.0" encoding="UTF-8"?>
2 DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
3 "http://www.springframework.org/dtd/spring-beans.dtd">
4 <beans>
5 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
6 <property name="driverClassName">
7 <value>com.mysql.jdbc.Drivervalue>
8 property>
9 <property name="url">
10 <value>jdbc:mysql://localhost:3306/Studentvalue>
11 property>
12 <property name="username">
13 <value>rootvalue>
14 property>
15 <property name="password">
16 <value>value>
17 property>
18 bean>
19 <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
20 <property name="dataSource">
21 <ref local="dataSource"/>
22 property>
23 <property name="mappingResources">
24 <list>
25 <value>limq/hibernate/vo/Admins.hbm.xmlvalue>
26 <value>limq/hibernate/vo/Classes.hbm.xmlvalue>
27 <value>limq/hibernate/vo/Courses.hbm.xmlvalue>
28 <value>limq/hibernate/vo/Students.hbm.xmlvalue>
29 <value>limq/hibernate/vo/ClassesInfo.hbm.xmlvalue>
30 <value>limq/hibernate/vo/Contact.hbm.xmlvalue>
31 <value>limq/hibernate/vo/Department.hbm.xmlvalue>
32 <value>limq/hibernate/vo/History.hbm.xmlvalue>
33 <value>limq/hibernate/vo/Teachers.hbm.xmlvalue>
34 list>
35 property>
36 <property name="hibernateProperties">
37 <props>
38 <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialectprop>
39 <prop key="hibernate.show_sql">trueprop>
40 props>
41 property>
42 bean>
43 <bean id="myTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
44 <property name="sessionFactory">
45 <ref local="sessionFactory"/>
46 property>
47