人在江湖

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            82 Posts :: 10 Stories :: 169 Comments :: 0 Trackbacks

          鏈接 在公司組建virtual團(tuán)隊(duì)(一) 在公司組建virtual團(tuán)隊(duì)(二) 大家都說沒有絕對好的技術(shù)框架,只有適合的。我覺得如果非要考量一種技術(shù)框架好壞,可以從兩個方面看,一看是否幫助程序員productive,二看是否靈活,適合實(shí)現(xiàn)細(xì)粒度的功能。通常這兩個方面互相矛盾。就好象NBA里力量和速度是兩個重要的身體素質(zhì)指標(biāo)。但是力量越好的,往往速度越差。NBA里最NB的往往是這兩方面協(xié)調(diào)的比較好的,比如很多人力量比小皇帝詹姆斯好,也有很多人速度比他快。但力量比他大的,速度都不如他;速度比他快的力量肯定比他差遠(yuǎn)了。這就是一個天賦球員。

          持久層可以用spring JDBC template, iBatis, Hibernate,當(dāng)然還有很多我不了解的。哦,別忘了還有ROO, 它也包含持久層的實(shí)現(xiàn),或者說,是很酷地封裝了其他框架的實(shí)現(xiàn)。

          對我來說,足夠productive的,只有Hibernate和ROO。跑了一遍ROO的PizzaShop的例子,真是太酷了。以前在Oracle的時候用過一個支持快速開發(fā)的產(chǎn)品叫Html DB,也很棒,但是ROO更透明,也更優(yōu)雅。ROO主要基于annotation和aspectj。生成一個簡單的應(yīng)用,只用10條左右的命令。從理論上說,ROO也適合控制細(xì)粒度的功能,可惜我不熟aspectJ以及它所采用的前端的技術(shù),猶豫了一下還是覺得走這條路風(fēng)險太大。但我非常看好ROO的發(fā)展,以后有時間要好好研究一下。喜歡ROO的另一個原因是,它生成的是Rich Model, 即使使用Hibernate.

          Hiberante也是我很喜歡的技術(shù),兩個原因,一是喜歡它transparent persistence的定位。二是它強(qiáng)調(diào)fine grained class,合俺胃口。Gavin在他的Hibernate書里(書可以從分享十二本經(jīng)典電子書這篇里找到)介紹了基于Hibernate做持久層的一個思路,很棒,如果說更具體的代碼實(shí)現(xiàn),可以看SpringSide2。事實(shí)上很多人現(xiàn)在都在采用這種方式封裝持久層。

          Spring提供了HibernateDaoSupport類對Hibernate支持,DAO類繼承了這個類之后,可以方便地得到HiberanteTemplate, 它的好處在于封裝了對session的管理,另外它也參與集成了對transaction的管理。SpringSide2主要基于HibernateDaoSupport和一些其他的技巧,實(shí)現(xiàn)了很薄的DAO層,基本上薄到?jīng)]有DAO層了。

             1: @Service
             2: public class BoardManager extends HibernateEntityDao<Board>{
             3: }

          上面這么一個空manager類,里面已經(jīng)包含關(guān)于Board類的CRUD的功能了,Board類是映射數(shù)據(jù)庫的一個貧血實(shí)體類。

          我?guī)缀鯖]有改SpringSide2對于Hibernate的封裝,改動只包含兩種:一種是把eclipse報warning給@SuppressWarnings(“unchecked”)掉了 另一種是把中文注釋翻譯成英文了。涉及到的java類在博客的最后有下載鏈接

          我們具體看看是怎么做到的。

          先寫個DAO的基類,叫做HibernateGenericDao。這個類對泛型或Object類封裝了CRUD的操作,以保證不依賴某個具體的實(shí)體類,看具體例子就能明白大體是怎么回事了

             1: public <T> T get(Class<T> entityClass, Serializable id) {
             2:     return (T) getHibernateTemplate().load(entityClass, id);
             3: }
             4:  
             5: public void remove(Object o) {
             6:     getHibernateTemplate().delete(o);
             7: }
             8:  
             9: public <T> void removeById(Class<T> entityClass, Serializable id) {
            10:     remove(get(entityClass, id));
            11: }

          這個類還有一個有技巧的地方在于:

             1: public <T> List<T> getAll(Class<T> entityClass, String orderBy, boolean isAsc) {
             2:     Assert.hasText(orderBy);
             3:     if (isAsc)
             4:         return getHibernateTemplate().findByCriteria(
             5:                 DetachedCriteria.forClass(entityClass).addOrder(Order.asc(orderBy)));
             6:     else
             7:         return getHibernateTemplate().findByCriteria(
             8:                 DetachedCriteria.forClass(entityClass).addOrder(Order.desc(orderBy)));
             9: }

          這里使用了DetachedCriteria. DetachedCriteria和Criteria有共同的父類。兩者的區(qū)別在于Criteria是在線的,而DetachedCreteria是離線的,也就是沒有session. 這樣正好可以用HibernateTemplate的session.

          繼續(xù)… 再寫一個子類:

             1: public class HibernateEntityDao<T> extends HibernateGenericDao

          在子類中,終于把泛型去掉了,舉例:

             1: protected Class<T> entityClass;// entity type that DAO manages
             2:  
             3: public HibernateEntityDao() {
             4:     entityClass = GenericsUtils.getSuperClassGenricType(getClass());
             5: }
             6:  
             7: protected Class<T> getEntityClass() {
             8:     return entityClass;
             9: }
            10:  
            11: public T get(Serializable id) {
            12:     return get(getEntityClass(), id);
            13: }

          這里的關(guān)鍵在于GenericsUtils.getSuperClassGenericType(getClass())

          最終調(diào)用到的code是:

             1: public static Class getSuperClassGenricType(Class clazz, int index) {
             2:  
             3:     Type genType = clazz.getGenericSuperclass();
             4:  
             5:     if (!(genType instanceof ParameterizedType)) {
             6:         log.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
             7:         return Object.class;
             8:     }
             9:  
            10:     Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
            11:  
            12:     if (index >= params.length || index < 0) {
            13:         log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
            14:                 + params.length);
            15:         return Object.class;
            16:     }
            17:     if (!(params[index] instanceof Class)) {
            18:         log.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
            19:         return Object.class;
            20:     }
            21:     return (Class) params[index];
            22: }

          略作說明:

          傳進(jìn)來的參數(shù)是org.emoticon.forum.manager.BoardManager

          genType是org.emoticon.core.persistence.HibernateEntityDao<org.emoticon.forum.model.Board>

          返回值是Board.

          通過這種方式,就實(shí)現(xiàn)了之前說的:

           

             1: public class RoleManager extends HibernateEntityDao<Role> {
             2:  
             3: }

          空manager類自動獲得CRUD的功能

          具體代碼可以從這里下載:

          http://cid-d8b11f9bf86fecfa.office.live.com/self.aspx/.Public/code/HibernateWrapper.zip

          posted on 2011-03-07 00:00 人在江湖 閱讀(1479) 評論(0)  編輯  收藏 所屬分類: hibernate
          主站蜘蛛池模板: 襄垣县| 永仁县| 湘潭市| 和平县| 双辽市| 徐水县| 绵阳市| 内黄县| 海原县| 抚远县| 双桥区| 黔南| 康乐县| 南京市| 荣成市| 桦川县| 朝阳县| 青岛市| 阳江市| 石狮市| 浦北县| 南溪县| 措勤县| 赤水市| 明溪县| 城市| 绿春县| 抚松县| 会宁县| 波密县| 安图县| 西乡县| 瑞昌市| 山西省| 象州县| 阳城县| 铜陵市| 卢龙县| 泗水县| 和平县| 江津市|