Struts作爲MVC 2的Web框架,自推出以來不斷受到開發者的追捧,得到廣泛的應用。作爲最成功的Web框架,Struts自然擁有衆多的優點:MVC 2模型的使用、功能齊全的標誌庫(Tag Library)、開放源代碼。而Spring的出現,在某些方面極大的方面了Struts的開發。同時,Hibernate作爲對象持久化的框架,能顯示的提高軟件開發的效率與生產力。這三種流行框架的整合應用,可以發揮它們各自的優勢,使軟件開發更加的快速與便捷。
struts2發佈已經很久了,但關於如何使用它的教程及實例並不多。特別是與Spring及Hibernate等流行框架的集成,並不多見。現在就將筆者使用Myeclipse工具應用struts2 + spring2 +hibernate3 實現CRUD操作的步驟一一紀錄下來,爲初學者少走彎路略盡綿薄之力!在本文中,筆者將Struts2.0.6、Spring2.0.6和Hibernate3.1進行整合,希望通過這樣的整合示例,讓讀者瞭解這些框架各自的特點,以便於在自己的項目中,根據實際情況,儘快的過渡到Struts2的時代。本文的內容基於Struts2.0.6。
一、準備工作
spring2與1.x區別不大,可以平滑的過度,筆者也是把spring1.28換成了spring2.0.6,算是升級到spring 2.0了。struts2基本就是webwork2.2,與以前的struts1.x可以說沒任何關係了。因爲是第一次用struts2,也是第一次用webwork,所以有很多不完善,不規範的地方,還望大家來拍磚。
開發環境:MyEclipse5.0+Eclipse3.2+JDK5.0+
Tomcat5.5+struts2+Spring2.0.6+Hibernate3.1。本示例通過對一個圖書進行管理的系統,提供基本的增加、刪除、修改、查詢等功能。
lib包需要以下右圖所示的這些包。其中Struts2.0.6的下載地址爲:
http://people.apache.org/builds/struts/2.0.6
Hibernate3.1的下載地址爲:
http://www.hibernate.org
spring2.0.6的下載地址爲:
http://www.springframework.org
使用的數據庫爲mysql 5.0,使用的JDBC驅動JAR包爲:mysql-connection-java-5.0.4-bin
創建數據表的sql語句爲:
createdatabase game
CREATETABLE `books` (
`book_id`int(11) NOT NULL default '0',
`book_name`varchar(200) character set gb2312 default NULL,
`book_author`varchar(100) character set gb2312 default NULL,
`book_publish`varchar(100) character set gb2312 default NULL,
`book_date`date default NULL,
`book_isbn`varchar(20) default NULL,
`book_page`int(11) default NULL,
`book_price`decimal(10,2) default NULL,
`book_content`varchar(100) character set gb2312 default NULL,
PRIMARYKEY (`book_id`)
)ENGINE=InnoDB DEFAULT CHARSET=gbk ROW_FORMAT=COMPRESSED;
二、建立公共類
1、AbstractAction類
Struts2和Struts1.x的差別,最明顯的就是Struts2是一個pull-MVC架構。Struts1.x 必須繼承org.apache.struts.action.Action或者其子類,表單數據封裝在FormBean中。Struts 2無須繼承任何類型或實現任何接口,表單數據包含在Action中,通過Getter和Setter獲取。
雖然,在理論上Struts2的Action無須實現任何接口或者是繼承任何的類,但是,在實際編程過程中,爲了更加方便的實現Action,大多數情況下都會繼承com.opensymphony.xwork2.ActionSupport類,並且重載(Override)此類裏的String execute()方法。因此先建立抽象類,以供其它Action類使用。
packagecom.sterning.commons;
importcom.opensymphony.xwork2.ActionSupport;
publicclass AbstractAction extends ActionSupport {
}
com.sterning.commons.AbstractAction.java
參考JavaDoc,可知ActionSupport類實現了接口:
com.opensymphony.xwork2.Action
com.opensymphony.xwork2.LoaleProvider
com.opensymphony.xwork2.TextProvider
com.opensymphony.xwork2.Validateable
com.opensymphony.xwork2.ValidationAware
com.uwyn.rife.continuations.ContinuableObject
java.io.Searializable
java.lang.Cloneable
2、Pager分頁類
爲了增加程序的分頁功能,特意建立共用的分頁類。
packagecom.sterning.commons;
importjava.math.*;
publicclass Pager {
privateint totalRows; //總行數
private int pageSize = 5; //每頁顯示的行數
private int currentPage; //當前頁號
private int totalPages; //總頁數
private int startRow; //當前頁在數據庫中的起始行
publicPager() {
}
publicPager(int _totalRows) {
totalRows= _totalRows;
totalPages=totalRows/pageSize;
intmod=totalRows%pageSize;
if(mod>0){
totalPages++;
}
currentPage= 1;
startRow= 0;
}
publicint getStartRow() {
returnstartRow;
}
publicint getTotalPages() {
returntotalPages;
}
publicint getCurrentPage() {
returncurrentPage;
}
publicint getPageSize() {
returnpageSize;
}
publicvoid setTotalRows(int totalRows) {
this.totalRows= totalRows;
}
publicvoid setStartRow(int startRow) {
this.startRow= startRow;
}
publicvoid setTotalPages(int totalPages) {
this.totalPages= totalPages;
}
publicvoid setCurrentPage(int currentPage) {
this.currentPage= currentPage;
}
publicvoid setPageSize(int pageSize) {
this.pageSize= pageSize;
}
publicint getTotalRows() {
returntotalRows;
}
publicvoid first() {
currentPage= 1;
startRow= 0;
}
publicvoid previous() {
if(currentPage == 1) {
return;
}
currentPage--;
startRow= (currentPage - 1) * pageSize;
}
publicvoid next() {
if(currentPage < totalPages) {
currentPage++;
}
startRow= (currentPage - 1) * pageSize;
}
publicvoid last() {
currentPage= totalPages;
startRow= (currentPage - 1) * pageSize;
}
publicvoid refresh(int _currentPage) {
currentPage= _currentPage;
if(currentPage > totalPages) {
last();
}
}
}
com.sterning.commons.Pager.java
同時,採用PagerService類來發布成爲分頁類服務PagerService,代碼如下:
packagecom.sterning.commons;
publicclass PagerService {
publicPager getPager(String currentPage,String pagerMethod,int totalRows) {
// 定義pager對象,用於傳到頁面
Pager pager = new Pager(totalRows);
// 如果當前頁號爲空,表示爲首次查詢該頁
// 如果不爲空,則刷新pager對象,輸入當前頁號等信息
if (currentPage != null) {
pager.refresh(Integer.parseInt(currentPage));
}
// 獲取當前執行的方法,首頁,前一頁,後一頁,尾頁。
if (pagerMethod != null) {
if(pagerMethod.equals("first")) {
pager.first();
}else if (pagerMethod.equals("previous")) {
pager.previous();
}else if (pagerMethod.equals("next")) {
pager.next();
}else if (pagerMethod.equals("last")) {
pager.last();
}
}
returnpager;
}
}
com.sterning.commons.PagerService.java
三、建立數據持久化層
1、編寫實體類Books及books.hbm.xml映射文件。
packagecom.sterning.books.model;
importjava.util.Date;
publicclass Books {
// Fields
private String bookId;//編號
private String bookName;//書名
private String bookAuthor;//作者
private String bookPublish;//出版社
private Date bookDate;//出版日期
private String bookIsbn;//ISBN
private String bookPage;//頁數
private String bookPrice;//價格
private String bookContent;//內容提要
// Constructors
public Books(){}
// Property accessors
public String getBookId() {
returnbookId;
}
publicvoid setBookId(String bookId) {
this.bookId= bookId;
}
publicString getBookName() {
returnbookName;
}
publicvoid setBookName(String bookName) {
this.bookName= bookName;
}
publicString getBookAuthor() {
returnbookAuthor;
}
publicvoid setBookAuthor(String bookAuthor) {
this.bookAuthor= bookAuthor;
}
publicString getBookContent() {
returnbookContent;
}
publicvoid setBookContent(String bookContent) {
this.bookContent= bookContent;
}
publicDate getBookDate() {
returnbookDate;
}
publicvoid setBookDate(Date bookDate) {
this.bookDate= bookDate;
}
publicString getBookIsbn() {
returnbookIsbn;
}
publicvoid setBookIsbn(String bookIsbn) {
this.bookIsbn= bookIsbn;
}
publicString getBookPage() {
returnbookPage;
}
publicvoid setBookPage(String bookPage) {
this.bookPage= bookPage;
}
publicString getBookPrice() {
returnbookPrice;
}
publicvoid setBookPrice(String bookPrice) {
this.bookPrice= bookPrice;
}
publicString getBookPublish() {
returnbookPublish;
}
publicvoid setBookPublish(String bookPublish) {
this.bookPublish= bookPublish;
}
}
com.sterning.books.model.Books.java
接下來要把實體類Books的屬性映射到books表,編寫下面的books.hbm.xml文件:
<?xmlversion="1.0"?>
<!DOCTYPEhibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<classname="com.sterning.books.model.Books" table="books" >
<id name="bookId"type="string">
<column name="book_id"length="5" />
<generatorclass="assigned" />
</id>
<property name="bookName"type="string">
<columnname="book_name" length="100" />
</property>
<propertyname="bookAuthor" type="string">
<columnname="book_author" length="100" />
</property>
<propertyname="bookPublish" type="string">
<columnname="book_publish" length="100" />
</property>
<property name="bookDate"type="java.sql.Timestamp">
<columnname="book_date" length="7" />
</property>
<propertyname="bookIsbn" type="string">
<columnname="book_isbn" length="20" />
</property>
<property name="bookPage"type="string">
<columnname="book_page" length="11" />
</property>
<property name="bookPrice"type="string">
<columnname="book_price" length="4" />
</property>
<propertyname="bookContent" type="string">
<columnname="book_content" length="100" />
</property>
</class>
</hibernate-mapping>
com.sterning.books.model.books.hbm.xml
2、hibernate.cfg.xml配置文件如下:(注意它的位置在scr/hibernate.cfg.xml)
<?xmlversion="1.0" encoding="ISO-8859-1"?>
<!DOCTYPEhibernate-configuration PUBLIC
"-//Hibernate/HibernateConfiguration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<propertyname="show_sql">true</property>
<mappingresource="com/sterning/books/model/books.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
Com.sterning.bean.hibernate.hibernate.cfg.xml