Struts是一個不錯的MVC架構,我一直以來都用它,通過簡單的配置即可將view,controler,和Model結合起來。View主要以JSP來實現,因爲它是面向標籤的,所以對於網頁設計人員提供了很好的接口。FormBean是介於JSP和Action之間的中間數據載體,它肩負着數據從JSP到ACTION的傳遞過程。Action是流程的中轉站,不同的業務在不同的Action中以不同的Model調用來實現。Model就是實現具體業務的操作過程,不過這種過程是一種在較高水平上的實現。
總之,MVC架構實現了三層結構中的兩層,即表現層和業務層,另外還有一層被稱之爲持久化層。
二、三層架構
正如以上所說的,三層架構即“表現層”,“業務層”,“持久化層”。表現層實現的代表作品是Struts框架,業務層實現的代表作品是Spring,持久層實現的代表作品是Hibernate。不過在我的開發中Spring被省掉了,因爲我認爲業務過於簡單,還不至於用Spring來實現。下面我將具體的來說說我的三層實現。
1、三種Bean
在我的實現中,總共有三種Bean,它們都是爲保存對象狀態而存在的。持久層中,這種Bean就是POJO對象。它是面向數據庫的,或者說多少得照顧到數據庫的實現,因爲我習慣於用PowerDesigner來設計數據庫,做出來的結構也是比較中規中矩的,而如果直接用Hibernate來實數據庫的話,就不那麼幹淨了。所以POJO對象的設計就不能完全面向對象。業務層中的Bean我把它稱之爲Entity,這是一個完全面向程序邏輯的Bean。它可能是好幾個POJO的集合。對於業務邏輯來,這種被稱之爲Entity的Bean做到了“拿來就用”,很便於業務的進行。在顯示層中的Bean就是FormBean了,主要用於傳入數據所用。
POJO僅生存於持久化層,到了業務層就將數據交給Entity了。而Entity不僅生存於業務層,它還被傳到了JSP中,用於顯示。
2、Pojo與Dao
我認爲這是數據與操作的關係,Dao只在呼操作,而Pojo僅用於保存數據。下面是我Dao接口的實個現。
public interface Dao {
//********** operattion method *********
void resetPO(Pojo pojo);//重新設置POJO實體
String save();//保存或更新POJO實體
Pojo load();//通過ID值獲取確切的POJO
List find(short by);//通過某一屬性值來獲取POJO
void close();//顯示調用,以關閉session,至此該DAO將不再可用。
}
所有的涉及具體操作的Dao類均實現它。三個方法把Hibernate的查詢語句封裝起來。在業務層中只關心save(),load(),或find()。下面是一個具體UserDao的實現。
public class UserDao implements Dao {
public final short _ALL = 0;
public final short _BY_NAME = 1;
public final short _BY_ACCOUNT = 2;
public final short _BY_PASSWORD = 3;
public final short _BY_ACCOUNT_PASSWORD = 4;
private UserPo userPo;
private static Log log = LogFactory.getLog(DocumentDAO.class);
private Session session;
//************ initial method ***************
public UserDao() {
userPo = new UserPo();
session = HibernateUtil.currentSession();
}
public UserDao(UserPo user){
this.userPo = user;
session = HibernateUtil.currentSession();
}
//************ method begin ***************
/**
* resetPO()
*重新加載POJO對象
* @param pojo Pojo
*/
public void resetPO(Pojo pojo) {
this.userPo = (UserPo)pojo;
}
/**
* save()
* 保存UserPo對象於數據庫,如果是一個已持久的對象,則進行update操作
* @return String
*/
public String save() {
String oid = null;
try{
//Session session = HibernateUtil.currentSession() 已經被提至構造函數中初始化了
Transaction tx = session.beginTransaction();
if (userPo.getId() == null) {
oid = (String)session.save(userPo);//如果這是一個新的pojo則進行insert操作。
session.flush();
tx.commit();
}else{
session.update(userPo,userPo.getId());//如果該pojo已被初始化過則進行update操作
session.flush();
tx.commit();
}
}catch(HibernateException ex){
System.out.println("//********* error **********///n UserDao.save()出現異常!");
log.error("UserDao.save()出現異常!",ex);
}
return oid;
}
/**
* get()
* 通過id值,從數據庫中獲得指定的UserPo對象
* @return Pojo
*/
public Pojo load() {
UserPo tmp = new UserPo();
try{
//Session session = HibernateUtil.currentSession() 已經被提至構造函數中初始化了
tmp = (UserPo) session.get(UserPo.class, userPo.getId()); //用確切存在的ID值獲得對象
}catch(HibernateException hbe){
hbe.printStackTrace();
}
if (tmp != null) {
userPo = tmp;
return userPo;
}
else
return null;
}
/**
* find()
* 從數據庫中查找一個User對象
* @return Pojo
*/
public List find(short by) {
//Session session = HibernateUtil.currentSession() 已經被提至構造函數中初始化了
Query query = null;
String where=null;
switch(by){
case 0 :
where = "";
break;
case 1 :
where = " where us.name='"+userPo.getName()+"'";
break;
case 2 :
where = " where us.account='"+userPo.getAccount()+"'";
break;
case 3 :
where = " where us.password='"+userPo.getPassword()+"'";
break;
case 4 :
where = " where us.account='"+userPo.getAccount()+"' and us.password='"+userPo.getPassword()+"'";
}
query = session.createQuery("from UserPo us"+where);
return query.list();
}
public void close(){
HibernateUtil.closeSession();
}
}
其中HibernateUtil是一個Hibernate方法類,它提供線程安全的Session。和關閉這個Session的方法(雖然關閉Session過於簡單)。每個Dao是由DaoFactory來產生的。DaoFactory也有一個公共的接口。如下:
public interface DaoFactory {
/**
* DAO對象工廠,獲取各個數據實體的DAO對象,返回一個統一的接口 Dao
* @return Dao
*/
Dao getDocumentDAO();
Dao getDocHeadDAO();
Dao getDocAccessoryDAO();
Dao getUserDao(User u);
}
下面是一個基於Hibernate的Dao的實現。
public class HbDaoFactory implements DaoFactory {
public HbDaoFactory() {
}
/**
* getDocumentDao
*
* @return Dao
*/
public Dao getDocumentDAO() {
/**@todo Implement this com.cecs.dao.DaoFactory method*/
return new com.cecs.dao.DocumentDAO();
}
/**
* getDocHeadDao
*
* @return Dao
*/
public Dao getDocHeadDAO() {
/**@todo Implement this com.cecs.dao.DaoFactory method*/
throw new java.lang.UnsupportedOperationException("Method getDocHeadDAO() not yet implemented.");
}
/**
* getDocAccessoryDao
*
* @return Dao
*/
public Dao getDocAccessoryDAO() {
/**@todo Implement this com.cecs.dao.DaoFactory method*/
throw new java.lang.UnsupportedOperationException("Method getDocAccessoryDAO() not yet implemented.");
}
/**
* getUserDao
*獲取UserDao對象
* @return Dao
*/
public Dao getUserDao(User u) {
return new UserDao(u);
}
}
這樣一但不用Hibernate來實現持久層,也可以很方便改爲其它的Dao而不用修改業務層。