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