學習最快的方式看代碼是一個很好的方法,到springside網站下栽springside-2.0-RC1-allinone.zip,看最簡單的例子helloword,
包結構很清晰,典型的mvc三層架構,model、service、web.
看一眼mode.User.java,數據庫的實體bean,沒什么可說的。
第二眼service.UserManager.java,心里想肯定是邏輯層中的Dao對數據庫的操作,增加、讀取、更新和刪除,editpus完后出乎我的意料
之外,里面沒有方法的實現
/**
* 用戶管理業務類.
* <p/>
* 繼承于HibernateEntityDao,不需任何代碼即擁有默認的對User對象的CRUD函數. 如果想了解不繼承于EntityDao,自行編寫CRUD的寫法, 參考{@link UserManagerNativeVersion}.
*
* @author calvin
* @see HibernateEntityDao
* @see org.springside.core.dao.HibernateGenericDao
* @see UserManagerNativeVersion
*/
public class UserManager extends HibernateEntityDao<User> {
// ....CRUD以外的其它商業方法
}
這里面出現了CRUD看完了才知道就是增加、讀取、更新和刪除幾個單詞的首字母簡寫 即Create,Read,Update,Delete四個單詞的縮寫。是數據庫操作的基本功,往往是程序員的入門級課程之一,也是最無聊的工作,在ROR中,這種工作被簡化了好多,很多很牛的Java程序員也自己寫了機器人去完成這些工作,這里的HibernateEntityDao<User>
肯定就是機器人了.
下面看機器人HibernateEntityDAO,查springside參考手冊知道它已存在默認的CRUD函數,子類只要用泛型語法聲明自己管理的Entity類型即可,如果你的Manager是簡單的CRUD類,沒有其他的商業方法,那就恭喜了,上面的代碼就是全部。
SpringSide是如何對進行Hibernate封裝的呢?看相關文檔如下:
SpringSide對Hibernate做了三層封裝:
第一層:HibernateGenericDao,基于spring的HibernateDaoSupport,但加入了分頁函數與各種Finder函數,并使用泛型避免了返回值強制類型轉換。
第二層:HibernateEntityDao,基于HibernateGenericDao,用泛型聲明Dao所管理的Entity類,默認擁有該entity的CRUD方法。
第三層:HibernateExtendDao,基于HibernateEntityDao,主要擴展各種選擇性的功能。
關于三個類的詳細注解請看JavaDoc,大致描述如下:
1 HibernateGenericDao
在Spring HibernateDaoSupport基礎上封裝的DAO,功能如下:
1.應用泛型:使得find(), get() 這些函數不再返回Object,而是返回T,不再需要強制類型轉換。
2.提供各種finder的簡便函數
應用了JDK5可變參數的hsql查詢函數:List find(String hql, Object... values),支持find(hql),find(hql, param1); find(hql,param1,param2);find(hql,new Object[] {param1,param2}) 四種接口。
簡單查詢的簡化函數:findBy(Class entityClass,String name,Object value) ,findUniqueBy(Class entityClass,String name, Object value),findByLike(Class entityClass,String name,Object value)
3.獲得設置好的Query和Criteria:createQuery(String hql,Object... values) 和 createCriteria(Class<T> entityClass,Criterion... criterions)
Spring并沒有很好的接口封裝支持firstResult, maxResult, fetchsize,cache,cacheRegion 等多個查詢參數,所以springside寧愿返回已設置好查詢條件的Query和Criteria,讓大家繼續剩下的參數設置,最后再執行list(),注意那幾個參數可以連續設置的,如:
createQuery(hql,param1).setFirstResult(10).setMaxResult(20).llist();
4.分頁函數:Page pagedQuery(Criteria criteria, int pageNo, int pageSize) 和Page pagedQuery(String hql, int pageNo, int pageSize, Object... args)
Page是SpringSide自行封裝的一個典型Page類,pagedQuery與hibernate自身分頁查詢的差別是先運行一次count,獲得符合條件的總記錄數。
如果查詢不需要總記錄數,用普通的hibernate API,加上setFirstResult(),setMaxResult()就解決,不需要pagedQuery()。
5.判別對象屬性在數據庫中唯一的函數:isUnique(Class<T> entityClass,Object entity,String names)。
2. HibernateEntityDao
所有UserManager, ProductManager之類只管理一類對象的Manager類的基類,只需要在類定義處聲明Entity類型即可
public class BookManager extends HibernateEntityDao<Book> {
}
通過<Book>的定義,避免了HibernateGenericDao類各方法中必有的Class entityClass參數。
如果需要操作其他的Entity,比如BookManager可能需要處理Category(圖書目錄),可以注入CategoryManager。無需擔心事務的問題,JavaEE的默認事務模型已能很好處理。
如果沒有對應的CategoryManager,或者各種原因不想注入的話,可以使用BookManager繼承自HibernateGenericDao的帶entityClass參數的函數來操作Category的增刪改,如Category category= this.get(Category.class, 1);
3. HibernateExtendDao
此類演示SpringSide 所作的一些擴展,大家可以按照自己的需要進行修改和擴展。
1. 支持對象不能被直接刪除,只能設置狀態列為無效。
接口UndeleteableEntityOperation,定義了要支持此功能必須實現的函數。
可以有接口(UndeletableEntity)和annotation(@Undeletable)兩種形式來定義無效列,annotation列形式還可以定義標識對象已刪除的狀態屬性的名稱,用接口則必須實現setStatus()接口,在里面操作實際的狀態屬性。
兩種方式的異同見侵入,非侵入?Interface vs Annotation。
2. 重載save(),在保存前先調用onValid() 函數
3. 增加find(Map map) 接口
默認查找與map中全部條件相同的entity。
條件的比較運算符默認為相同,用戶也可以為屬性名加上like_,largerthen_ 這樣的前綴,則使用相應的運算符作比較(未完成)
第三眼 看web.UserAction.java,心想應該和struts里的acition一樣,editpuls完后得到
/**
* 用戶管理Controller.
* <p/>
* 繼承于StrutsEntityAction,不需編碼就擁有默認的對User對象的CRUD響應函數. 如果想了解不繼承于EntityAction,自行編寫CRUD的寫法, 參考{@link UserActionNativeVersion}.
*
* @author calvin
* @see org.springside.core.web.StrutsEntityAction
* @see org.springside.core.web.StrutsAction
* @see UserActionNativeVersion
*/
public class UserAction extends StrutsEntityAction<User, UserManager> {
@SuppressWarnings("unused")
private UserManager userManager; //看到serviceContext.xml中面有userManager應該是spring的注入
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
}
第四眼 看了web.xml、struts-config.xml、applicationContext.xml、dataAccessContext.xml、serviceContext.xml 五個配置文件。
接下來調試程序,用運成功。