SSH框架整合
一、原理圖
action:(struts2)
1、獲取表單的數據
2、表單的驗證,例如非空驗證,email驗證等
3、調用service,並把數據傳遞給service
Service:業務層
增刪改查,比如:登錄,調用dao的query方法進行查詢,返回結果,進行用戶名密碼的比對,將結果返回給action
Dao(hibernate)save、delete、update、query
Spring
1、ioc,由spring管理創建、銷毀action、service、dao
Java本身(實現接口),cglib(第三方的jar包)
2、aop,管理service的事務
二、整體結構
src根目錄
1、com.jsoft.action包
2、com.jsoft.hbm.dao包:連接數據庫的dao
3、com.jsoft.hbm.orm包:hibernate實體類和關系映射文件
4、com.jsoft.services.impl包:service的具體實現
5、applicationContext.xml:spring配置文件
1.配置.xsd
2.配置數據庫連接池,與hibernate無關
舉例子:網線
上課需要網線,來一個同學上課需要拉一根網線,陸陸續續來二十多個同學就要陸陸續續拉二十跟網線,效率低,想要提高效率就要估計要來的學生數假定為23,那么就直接事先拉30根網線,留出7根網線作備用
提出:假如沒有數據庫連接池,有一個用戶需要做查詢就需要跟數據庫做一個連接,當又有一個用戶做查詢還要建立連接,這樣做耗時長,而且非常耗費資源
當有數據庫連接池時: 啟動服務時就建立若干個連接,沒有用戶用也先放着,當有一個用戶需要訪問的時候就在連接池中挑一個空閑的連接給用戶做增刪改查的操作,以此類推,並發執行。並發執行操作時不需要和數據庫建立連接,效率高。用戶1完成操作后就釋放連接到連接池中已備其他用戶使用,用來循環使用。如果若干連接都被使用就繼續建立若干個連接以供備用。
該ssh框架用的是c3p0數據庫連接池,是hibernate推薦是用的。
3.配置hibernate的session工廠
Hibernate本身就有一個session工廠,而在這里我們用的是spring配
置的session工廠,為了hibernate和spring更好的集成。
第一、注入dataSource
Property中的ref屬性的意思是把id=dataSource的對象1注入到2這個類的name為dataSource的成員變量3中,其中1與4對應。Ref表示注入的是對象類型,基本數據類型用value
第二、采用通配符的方式配置加載.hbm.xml的映射文件,.配置方言、顯示sql、格式化sql。
4.配置事務管理器
第一、注入(同上)
第二、定義事務通知,定義方法的過濾規則,save*等表示當方法名滿足save等為前綴的時候會自動加上事務。也就是說具體的service層和action層代碼增刪改查方法名必須以這幾個為前綴,否則報錯。
意思是session沒有綁定事務。
第三、定義aop,表示的是事務具體加在了哪里,與過濾規則相互配合管理事務
5.啟用cglib
6.把sessionFactory注入到BaseHibernateDAO的成員變量sessionFactory中
7.這里寫其他的bean
=================這是一條分割=========================
6、struts.properties:struts2常量配置
創建.properties文件的方法是新建file,后綴為.properties
注意:struts.objectFactory=spring指的是把對象工廠指向spring,表示由spring創建對象。(與三、6相對應)
7、struts.xml:struts配置文件
//這里寫**.jsp
WebContent根目錄
8、META-INF文件夾
9、WEB-INF文件夾
1、lib文件夾:
引入的是ssh框架的jar包
【struts2版本2.3.24】【spring版本3.2.0】【hibernate版本4.2.4】
2、web.xml:
啟動web容器時,spring容器也跟着啟動,接着讀取applicationContext里的配置文件,里面包含:指定spring配置文件的路徑和名稱,其中的classpath指的是src根目錄下、struts2過濾器、通過監聽器的方式啟動spring
3、各種jsp頁面
三、登錄功能具體代碼【web工程】
1、對於com.jsoft.hbm.orm包
創建數據庫表對應的實體類Student,編寫映射文件,在編寫好的映射文件中修改主鍵生成方式為uuid.hex,以及數據庫中有下划線的數據要添加下划線
2、編寫視圖層登錄頁面login.jsp
表單提交時傳遞的參數name屬性值為username和password。記得修改兩個地方編碼集為utf-8和刪除pageEncoding="ISO-8859-1"。如果jsp文件中第一行的<%報錯,就右鍵WebContent選中build path的configure build path,在右側選第四個add library,選中server runtime選next,選中tomcat點擊finish。
2、在com.jsoft.services.impl包中創建LoginService類
①創建BaseHibernateDAO類的成員變量dao,並獲取set方法
②編寫querylogin方法
注意返回的是一個Map,因此新建一個Map對象returnMap用來存放數據和當做返回值。然后還要有表單提交來的name值為username和password的數據。然后用成員變量dao調用query方法編寫hql語句並用List變量接收,判斷如果不空就創建學生類對象s並獲取password與表單傳遞過來的password值作比較,並用put方法加入到returnMap中,如果相等就設置code值為1表示登陸成功;如果不相等就設置code值為-1表示密碼錯誤。如果list為空就設置code值為-1表示用戶名密碼不匹配。
3、在com.jsoft.action包中編寫LoginAction類
①繼承ActionSupport類
②定義成員變量username,password,還有LoginService類的成員變量loginService並獲取他們的set方法
③重寫excute方法
定義Map變量map,用put方法放入表單提交來的數據username,password,注意表單、aaction、sevice中的username和password要一一對應相等。用LoginService類的成員變量loginService調用querylogin方法參數為map,定義Map變量resultMap接收,判斷傳遞過來的code值,如果是1則跳轉成功頁面,否則跳轉登錄頁面。
4、配置service
在spring的配置文件applicationContext.xml中新建標簽,用到id屬性和類同名為LoginService,class屬性寫的是LoginService的路徑名com.jsoft.services.impl.LoginService(建議用粘貼復制,寫好之后點擊檢查)。在bean標簽里面寫標簽編寫注入代碼,屬性值為name里面寫要注入的成員變量名dao,屬性值ref寫的是要注入id值為BaseHibernateDAO的對象。
5、配置action
同樣在之后新建標簽,用到id屬性和類同名為LoginAction,class屬性寫的是LoginAction的包名加類名。在所有action配置中添加scope="prototype",表示多實例模式,一般情況,action有成員變量,采用單例模式會發生緩存上一次的紀錄,所以要采用多實例模式。也就是說有成員變量就用多實例模式。
6、在struts.xml中配置action
新建標簽,用到name屬性和class屬性,name屬性寫的是表單里面的action屬性名login;其中class屬性不能寫類的全路徑,而應該是spring配置文件中的的id屬性值LoginAction,原因是由spring管理對象,(與二、6相對應)如果寫的是類的全路徑,那么在struts2中會根據全路徑自己創建對象,但采用這種方式不會在這個類里面注入LoginService這個成員變量,會報的是空指針。
然后在action標簽里編寫標簽表示結果,如果成功name屬性值為success,跳轉到loginSuccess.jsp;如果失敗name屬性值為login,跳轉類型type屬性值為redirect方式,跳轉到login.jsp。
四、登錄功能ssh框架具體執行流程
當點擊提交按鈕時,將請求發送給login.action,被過濾器所攔截,過濾器就知道當前訪問資源是login.action,根據action這個名稱會到struts.xml配置中找與之相匹配的name屬性值為login的action,然后找class屬性,又因為在常亮配置中有struts.objectFactory=spring這句話,知道class里面不是類的名稱而是spring的id,然后會到spring容器applicationContext.xml中找id為LoginAction的bean,之后spring會自行實例化class屬性里面的類,然后還會檢測到要往這個類的成員變量中注入loginService這個對象,然后還會找到id為LoginService的bean,接下來還會實例化class里面的類,還會檢測到要往這個類的成員變量dao中注入BaseHibernateDAO這個類,然后找到id為BaseHibernateDAO的bean,實例化class里面的類,還會檢測到要往這個類的成員變量sessionFactory里注入sessionFactory。接下來會把實例化好的BaseHibernateDAO這個類的對象傳遞給dao這個成員變量中,接下來在把LoginService注入到loginService這個成員變量中。然后在struts.xml配置文件中才可以用LoginAction這個對象,然后把請求轉交給LoginAction這個對象,然跳到LoginAction這個類。然后把相應的從表單傳遞過來的值放到Map中,然后調用LoginService,在里面調用dao的query方法,然后返回code值給LoginAction類,根據判斷跳轉到相應的頁面。
如果該org.jsoft.hbn...要改下面對應的地方
五、增加功能具體代碼
1、編寫視圖層增加頁面addStudent.jsp
表單提交時傳遞的參數name屬性值為student.name和student.age。其他同上。
2、com.jsoft.services.impl包,創建StudentService類
①創建BaseHibernateDAO類的成員變量dao,並獲取set方法
②編寫增加方法save【注意方法名要遵守事務規則】
注意形參類型為Student,然后用dao調用BaseHibernateDAO類中的save方法傳遞參數為剛才的形參student,返回的是一個Serializable【序列化的接口,基本數據類型,字符串等等一些類都實現這個接口,一會返回的時候可以把它強轉為字符串這個字符串就是主鍵】,也就是id,【因為之前設置的主鍵生成方式為uuid,返回的不知道是什么,hibernate為了讓我們知道,做保存時返回一個字符串的對象】,強轉並輸出id。
3、在com.jsoft.action包中編寫AddStudentAction類
①繼承ActionSupport類
②創建Student類對象student【因為表單傳遞過來的是對象類型,所以要有get方法】,定義StudentService類的成員變量studentService並獲取他們的set方法
③重寫excute方法
用studentService調用save方法傳遞參數為student
4、配置service
5、配置action
6、在struts.xml中配置action
六、查詢功能具體代碼
1、在com.jsoft.services.impl包中的StudentService類中添加查詢方法query【注意方法名要遵守事務規則】
注意返回的是一個Map,因此新建一個Map對象returnMap用來存放數據和當做返回值。用dao調用query方法,第一個參數是編寫hql語句,此處為from Student,第二個參數是查詢條件,此處做簡單查詢返回null,返回值是List類型,定義list變量接收。然后把結果放到returnMap中,最后返回returnMap。
2、在com.jsoft.action包中編寫ShowStudentAction類
①繼承ActionSupport類
②定義StudentService成員變量studentService並獲得set方法
③重寫excute方法
在里面用studentService這個成員變量調用query方法傳遞參數為null,定義Map類型的變量resultMap用來接收,再用resultMap調用get方法,里面的字符串類型的k值必須和上面put的k值一樣是list,然后用List類型的變量list接收,強轉list。接下來把list穿傳回到結果頁面中,定義List類型的成員變量list,並且要有get方法,把之前定義的List局部變量刪除。
3、配置service【用上面配置的就可以】
4、配置action
5、在struts.xml中配置action
6、創建顯示結果jsp:showStudentList.jsp【用到jstl和el表達式】
引入jstl標簽庫:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
Table標簽里面首先寫一個tr若干個td,分別表示編號姓名年齡,之后調用c標簽的forEach方法,里面添加items屬性獲取到list,添加var屬性里面寫item,添加varStatus屬性定義變量名vs,在后面調用時用vs.count顯示對應序號。
之后復制之前寫的trtd到forEach里面,用item分別點出相應的屬性
七、查詢功能運行流程:
首先訪問showStudentList這個action,才能到達列表頁面,然后將這個請求發送到ShowStudentAction這個action中然后調用StudentService的query方法,在里面執行查詢,結果返回到action中,在action中在吧這個成員變量取出來放到list中,又因為有get方法所以將這個數據傳遞到jsp里,然后顯示頁面。注意直接訪問jsp沒有用,因為沒有進入到action,也就沒調用service進行查詢,就不會有相應的結果。
八、刪除功能具體代碼
1、在com.jsoft.services.impl的StudentService類中編寫通過id刪除的方法deleteById
返回值類型是int,形參為String,String變量名為id,用dao調用update方法,里面的第一個屬性寫hql語句,第二個屬性為String類型的id,將整個結果返回。
2、com.jsoft.action包,寫DeleteStudentByIdAction類
①繼承ActionSupport類
②定義StudentService成員變量studentService和Student類成員變量id並獲得相應的set方法
③重寫excute方法
用studentService調用deleteById這個方法,參數傳遞id
3、在applicationContext.xml中配置service【因為之前已經配置好了,所以不用配置】和action【注意把action配置成多實例模式scope="prototype"】
4、配置struts.xml
6、在showStudentList.jsp頁面里編寫
首先添加一個td,寫操作,然后在c標簽里用a標簽寫修改和刪除
刪除 然后寫script標簽,用function定義方法deleteById,參數傳遞為id,用if添加一個判斷條件為confirm,里面內容寫的是:location.href = "deleteStudentById.action?id=" + id
九、修改功能具體代碼
1、在org.jsoft.services.impl中的StudentService類中添加通過傳過來的id查詢的方法queryById
返回值類型是Student,形參為String,String變量名為id,用dao調用getById方法,里面的第一個屬性寫Student.class,第二個屬性為id,【注意這個id不用加雙引號】將整個結果返回。
2、org.jsoft.actions包中創建ShowStudentByIdAction類
①繼承ActionSupport類
②創建私有的成員變量並獲取相應的get和set方法:String類型的變量id,Student類型的s,StudentService類型的studentService
③重寫excute方法
用studentService調用queryById方法,傳入參數為id【注意:此處的id也不是字符串類型的】,用Student對象s接收
3、在applicationContext.xml中配置service【上面配置過了所以不用配置】和action【注意把action配置成多實例模式scope="prototype"】
4、配置struts.xml中配置ShowStudentByIdAction
成功之后跳轉到回顯頁面showStudentById.jsp
5、在showStudentList.jsp中的修改部分添加超鏈接:
修改
【意思是點擊修改時跳轉到action名為showStudentById的struts.xml中】
6、編寫回顯頁面showStudentById.jsp
和添加頁面相似,復制粘貼,在form表單中添加屬性method以post方式提交,在input標簽中添加傳入的id,然后分別在后面添加value屬性,里面寫EL表達式用在ShowStudentByIdAction類中創建的Student成員變量s調用student的具體屬性,注意在這個類中必須用s接收,即s=XXX,然后把添加按鈕改成修改,最后把表單提交到updateStudent.action。
【現在已經通過id查詢到要修改的字段了,接下來要真正執行修改操作了】
7、在org.jsoft.services.impl中的StudentService類中添加通過傳過來的id查詢的方法update
返回值類型為void,參數類型為Student參數為student,用dao調用update方法,參數為剛創建的student。
8、在org.jsoft.actions包中創建UpdateStudentAction類
①繼承ActionSupport類
②創建私有的成員變量:Student類實例對象student【new】,StudentService類的對象studentService
③重寫excute方法
用studentService調用update方法,參數為剛創建的student
9、在applicationContext.xml中配置service【上面配置過了所以不用配置】和action【注意把action配置成多實例模式scope="prototype"】
10、配置struts.xml中配置UpdateStudentAction
成功之后跳轉到之前的展示頁面showStudentList.jsp
注意在result標簽中修改跳轉類型為type="redirect"
十、修改功能運行流程:
【大概流程是先查詢到要修改一列對應的id,跳轉到回顯頁面進行修改,修改之后再跳回到之前的展示頁面】具體如下:
在展示頁面的對應行中點擊修改按鈕后,獲取到id值,並訪問showStudentById.action,也就是在struts.xml配置中找到action名為showStudentById的部分,運行到class屬性時找到id名為ShowStudentByIdAction的applicationContext.xml配置中的bean標簽對應部分,進入到class路徑下的org.jsoft.actions.ShowStudentByIdAction中,在這個類中定義String類型的變量id存剛才從鏈接傳入的id,將查詢出來的結果封裝到Student類型變量s中,編寫回顯頁面showStudentById.jsp,用EL表達式調用剛才封裝到s中的各種要修改的屬性並進行相應的修改【注意還要傳遞一個id,因為是根據id修改,如果不傳遞id報錯如下:】
最后以post方式提交到updateStudent.action,,也就是在struts.xml配置中找到action名為updateStudent的部分,運行到class屬性時找到id名為UpdateStudentAction的applicationContext.xml配置中的bean標簽對應部分,進入到class路徑下的org.jsoft.actions.UpdateStudentAction中,在這個類中創建Student實例對象student,將修改好的數據封裝到里面,用studentService對象調用編寫的update方法把修改的數據寫入數據庫,之后回到applicationContext.xml中,將studentService注入到StudentService中,最后回到struts.xml中通過重定向的方式type="redirect"跳轉到結果展示頁面showStudentList.action展示出修改的結果。