Struts做爲MVC 2的Web框架,自推出以來不斷受到開發者的追捧,獲得普遍的應用。做爲最成功的Web框架,Struts天然擁有衆多的優勢:MVC 2模型的使用、功能齊全的標誌庫(Tag Library)、開放源代碼。而Spring的出現,在某些方面極大的方面了Struts的開發。同時,Hibernate做爲對象持久化的框架,能顯示的提升軟件開發的效率與生產力。這三種流行框架的整合應用,能夠發揮它們各自的優點,使軟件開發更加的快速與便捷。
struts2發佈已經好久了,但關於如何使用它的教程及實例並很少。特別是與Spring及Hibernate等流行框架的集成,並很少見。如今就將筆者使用Myeclipse工具應用struts2 + spring2 + hibernate3 實現CRUD操做的步驟一一紀錄下來,爲初學者少走彎路略盡綿薄之力!在本文中,筆者將Struts2.0.六、Spring2.0.6和Hibernate3.1進行整合,但願經過這樣的整合示例,讓讀者瞭解這些框架各自的特色,以便於在本身的項目中,根據實際狀況,儘快的過渡到Struts2的時代。本文的內容基於Struts2.0.6。
1、 準備工做
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語句爲:
create database game
CREATE TABLE `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,
PRIMARY KEY (`book_id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk ROW_FORMAT=COMPRESSED;
2、 創建公共類
一、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)
package com.sterning.commons;
import com.opensymphony.xwork2.ActionSupport;
public class 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
二、Pager分頁類
爲了增長程序的分頁功能,特地創建共用的分頁類。
package com.sterning.commons;
import java.math.*;
public class Pager {
private int totalRows; //總行數
private int pageSize = 5; //每頁顯示的行數
private int currentPage; //當前頁號
private int totalPages; //總頁數
private int startRow; //當前頁在數據庫中的起始行
public Pager() {
}
public Pager(int _totalRows) {
totalRows = _totalRows;
totalPages=totalRows/pageSize;
int mod=totalRows%pageSize;
if(mod>0){
totalPages++;
}
currentPage = 1;
startRow = 0;
}
public int getStartRow() {
return startRow;
}
public int getTotalPages() {
return totalPages;
}
public int getCurrentPage() {
return currentPage;
}
public int getPageSize() {
return pageSize;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
}
public void setStartRow(int startRow) {
this.startRow = startRow;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalRows() {
return totalRows;
}
public void first() {
currentPage = 1;
startRow = 0;
}
public void previous() {
if (currentPage == 1) {
return;
}
currentPage--;
startRow = (currentPage - 1) * pageSize;
}
public void next() {
if (currentPage < totalPages) {
currentPage++;
}
startRow = (currentPage - 1) * pageSize;
}
public void last() {
currentPage = totalPages;
startRow = (currentPage - 1) * pageSize;
}
public void refresh(int _currentPage) {
currentPage = _currentPage;
if (currentPage > totalPages) {
last();
}
}
}
com.sterning.commons.Pager.java
同時,採用PagerService類來發布成爲分頁類服務PagerService,代碼以下:
同時,採用PagerService類來發布成爲分頁類服務PagerService,代碼以下:
package com.sterning.commons;
public class PagerService {
public Pager 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();
}
}
return pager;
}
}
3、 創建數據持久化層
一、編寫實體類Books及books.hbm.xml映射文件。
package com.sterning.books.model;
import java.util.Date;
public class 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() {
return bookId;
}
public void setBookId(String bookId) {
this.bookId = bookId;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getBookAuthor() {
return bookAuthor;
}
public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}
public String getBookContent() {
return bookContent;
}
public void setBookContent(String bookContent) {
this.bookContent = bookContent;
}
public Date getBookDate() {
return bookDate;
}
public void setBookDate(Date bookDate) {
this.bookDate = bookDate;
}
public String getBookIsbn() {
return bookIsbn;
}
public void setBookIsbn(String bookIsbn) {
this.bookIsbn = bookIsbn;
}
public String getBookPage() {
return bookPage;
}
public void setBookPage(String bookPage) {
this.bookPage = bookPage;
}
public String getBookPrice() {
return bookPrice;
}
public void setBookPrice(String bookPrice) {
this.bookPrice = bookPrice;
}
public String getBookPublish() {
return bookPublish;
}
public void setBookPublish(String bookPublish) {
this.bookPublish = bookPublish;
}
}
com.sterning.books.model.Books.java
接下來要把實體類Books的屬性映射到books表,編寫下面的books.hbm.xml文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sterning.books.model.Books" table="books" >
<id name="bookId" type="string">
<column name="book_id" length="5" />
<generator class="assigned" />
</id>
<property name="bookName" type="string">
<column name="book_name" length="100" />
</property>
<property name="bookAuthor" type="string">
<column name="book_author" length="100" />
</property>
<property name="bookPublish" type="string">
<column name="book_publish" length="100" />
</property>
<property name="bookDate" type="java.sql.Timestamp">
<column name="book_date" length="7" />
</property>
<property name="bookIsbn" type="string">
<column name="book_isbn" length="20" />
</property>
<property name="bookPage" type="string">
<column name="book_page" length="11" />
</property>
<property name="bookPrice" type="string">
<column name="book_price" length="4" />
</property>
<property name="bookContent" type="string">
<column name="book_content" length="100" />
</property>
</class>
</hibernate-mapping>
com.sterning.books.model.books.hbm.xml
二、hibernate.cfg.xml配置文件以下:(注意它的位置在scr/hibernate.cfg.xml)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="show_sql">true</property>
<mapping resource="com/sterning/books/model/books.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
Com.sterning.bean.hibernate.hibernate.cfg.xml
4、 創建DAO層
DAO訪問層負責封裝底層的數據訪問細節,不只可使概念清晰,並且能夠提升開發效率。
一、創建DAO的接口類:BooksDao
package com.sterning.books.dao.iface;
import java.util.List;
import com.sterning.books.model.Books;
public interface BooksDao {
List getAll();//得到全部記錄
List getBooks(int pageSize, int startRow);//得到全部記錄
int getRows();//得到總行數
int getRows(String fieldname,String value);//得到總行數
List queryBooks(String fieldname,String value);//根據條件查詢
List getBooks(String fieldname,String value,int pageSize, int startRow);//根據條件查詢
Books getBook(String bookId);//根據ID得到記錄
String getMaxID();//得到最大ID值
void addBook(Books book);//添加記錄
void updateBook(Books book);//修改記錄
void deleteBook(Books book);//刪除記錄
}
com.sterning.books.dao.iface.BooksDao.java
二、實現此接口的類文件,BooksMapDao
package com.sterning.books.dao.hibernate;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.sterning.books.dao.iface.BooksDao;
import com.sterning.books.model.Books;
import com.sterning.commons.PublicUtil;
/** *//**
* @author cwf
*
*/
public class BooksMapDao extends HibernateDaoSupport implements BooksDao {
public BooksMapDao(){}
/** *//**
* 函數說明:添加信息
* 參數說明:對象
* 返回值:
*/
public void addBook(Books book) {
this.getHibernateTemplate().save(book);
}
/** *//**
* 函數說明:刪除信息
* 參數說明: 對象
* 返回值:
*/
public void deleteBook(Books book) {
this.getHibernateTemplate().delete(book);
}
/** *//**
* 函數說明:得到全部的信息
* 參數說明:
* 返回值:信息的集合
*/
public List getAll() {
String sql="FROM Books ORDER BY bookName";
return this.getHibernateTemplate().find(sql);
}
/** *//**
* 函數說明:得到總行數
* 參數說明:
* 返回值:總行數
*/
public int getRows() {
String sql="FROM Books ORDER BY bookName";
List list=this.getHibernateTemplate().find(sql);
return list.size();
}
/** *//**
* 函數說明:得到全部的信息
* 參數說明:
* 返回值:信息的集合
*/
public List getBooks(int pageSize, int startRow) throws HibernateException {
final int pageSize1=pageSize;
final int startRow1=startRow;
return this.getHibernateTemplate().executeFind(new HibernateCallback(){
public List doInHibernate(Session session) throws HibernateException, SQLException {
// TODO 自動生成方法存根
Query query=session.createQuery("FROM Books ORDER BY bookName");
query.setFirstResult(startRow1);
query.setMaxResults(pageSize1);
return query.list();
}
});
}
/** *//**
* 函數說明:得到一條的信息
* 參數說明: ID
* 返回值:對象
*/
public Books getBook(String bookId) {
return (Books)this.getHibernateTemplate().get(Books.class,bookId);
}
/** *//**
* 函數說明:得到最大ID
* 參數說明:
* 返回值:最大ID
*/
public String getMaxID() {
String date=PublicUtil.getStrNowDate();
String sql="SELECT MAX(bookId)+1 FROM Books ";
String noStr = null;
List ll = (List) this.getHibernateTemplate().find(sql);
Iterator itr = ll.iterator();
if (itr.hasNext()) {
Object noint = itr.next();
if(noint == null){
noStr = "1";
}else{
noStr = noint.toString();
}
}
if(noStr.length()==1){
noStr="000"+noStr;
}else if(noStr.length()==2){
noStr="00"+noStr;
}else if(noStr.length()==3){
noStr="0"+noStr;
}else{
noStr=noStr;
}
return noStr;
}
/** *//**
* 函數說明:修改信息
* 參數說明: 對象
* 返回值:
*/
public void updateBook(Books pd) {
this.getHibernateTemplate().update(pd);
}
/** *//**
* 函數說明:查詢信息
* 參數說明: 集合
* 返回值:
*/
public List queryBooks(String fieldname,String value) {
System.out.println("value: "+value);
String sql="FROM Books where "+fieldname+" like '%"+value+"%'"+"ORDER BY bookName";
return this.getHibernateTemplate().find(sql);
}
/** *//**
* 函數說明:得到總行數
* 參數說明:
* 返回值:總行數
*/
public int getRows(String fieldname,String value) {
String sql="";
if(fieldname==null||fieldname.equals("")||fieldname==null||fieldname.equals(""))
sql="FROM Books ORDER BY bookName";
else
sql="FROM Books where "+fieldname+" like '%"+value+"%'"+"ORDER BY bookName";
List list=this.getHibernateTemplate().find(sql);
return list.size();
}
/** *//**
* 函數說明:查詢信息
* 參數說明: 集合
* 返回值:
*/
public List getBooks(String fieldname,String value,int pageSize, int startRow) {
final int pageSize1=pageSize;
final int startRow1=startRow;
final String queryName=fieldname;
final String queryValue=value;
String sql="";
if(queryName==null||queryName.equals("")||queryValue==null||queryValue.equals(""))
sql="FROM Books ORDER BY bookName";
else
sql="FROM Books where "+fieldname+" like '%"+value+"%'"+"ORDER BY bookName";
final String sql1=sql;
return this.getHibernateTemplate().executeFind(new HibernateCallback(){
public List doInHibernate(Session session) throws HibernateException, SQLException {
// TODO 自動生成方法存根
Query query=session.createQuery(sql1);
query.setFirstResult(startRow1);
query.setMaxResults(pageSize1);
return query.list();
}
});
}
} java