Goingmm

            BlogJava :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理 ::
            82 隨筆 :: 15 文章 :: 452 評論 :: 0 Trackbacks

              
               周末和 MIKE 吃飯的時候,他詢問,上次提說的問題,什么時候能寫出來。“對SessionTransaction的處理,最好單獨實現一個模板類來統一做”

           

          溫故 居于常規的HibernateDAO代碼。例子做一個Create操作

           1public void createPerson() {
           2        Session session = null;
           3        Transaction tran = null;
           4        try {
           5            // Obtain Session
           6            Configuration config = new Configuration()
           7                    .configure();
           8            SessionFactory sessionFactory = config.buildSessionFactory();
           9            session = sessionFactory.openSession();
          10
          11            // Obtain Transaction
          12            tran = session.beginTransaction();
          13
          14            // Obtain Person
          15            Person person = new Person();
          16            person.setPersonName("IBM");
          17            person.setPersonEmail("goingmm@gmail.com");
          18            person.setPersonSex("M");
          19            // Create Person
          20            session.save(person);
          21            session.flush();
          22            tran.commit(); // 這步安全執行后,Person真正寫入數據庫
          23        }
           catch (HibernateException e) {
          24            e.printStackTrace();
          25            if (tran != null{
          26                try {
          27                    tran.rollback();
          28                }
           catch (HibernateException ex) {
          29                    ex.printStackTrace();
          30                }

          31            }

          32        }
           finally {
          33            if (session != null)
          34                session.close();
          35        }

          36    }

          37


               這段代碼怎么樣? 假如這樣的代碼會出現在你的每一個DAO的每一個方法里面(除了SessionFactory建議寫成一個方法,因為你只需要一個實例)你能接受嗎?只說try catch 就夠你寫的。

          如果代碼在每個地方都出現。那么我想就可以抽離出來。做成一個模板。具體該怎么做呢?今天我打算談三種比較成熟的做法。

                采用Spring提供的模板功能

                自己實現一個功能相當的模板

                其他可借鑒的實現

           

          采用Spring提供的模板功能

          看代碼:

                   

           1     public class PersonHibernateDao extends HibernateDaoSupport implements IPersonDao{
           2
           3         public void saveUser(Person person){
           4
           5              getHibernateTemplate().saveOrUpdate(person);
           6
           7         }

           8
           9     }

          10

           

               比起上面的代碼,現在簡單多了吧?其實該做的事情都做了,只不過是被Spring封裝起來了。大致跟蹤一下SpringSourceCode的實現。

          1)   在抽象類HibernateDaoSupport中有一個方法getHibernateTemplate()。通過getHibernateTemplate()得到一個HibernateTemplate對象。

          2)   HibernateDaoSupport中有兩個方法。通過他們來的到這個 HibernateTemplate對象

           1public final void setSessionFactory(SessionFactory sessionFactory) {
           2
           3  this.hibernateTemplate = createHibernateTemplate(sessionFactory);
           4
           5}

           6
           7protected HibernateTemplate createHibernateTemplate(SessionFactory sessionFactory) {
           8
           9     return new HibernateTemplate(sessionFactory);
          10
          11}

          12


          3)   找到saveOrUpdate()方法

           1public void saveOrUpdate(final Object entity) throws DataAccessException {
           2   execute(new HibernateCallback() // call execute() 
           3// 這里使用了匿名內部類 來實現doInHibernate()
           4     public Object doInHibernate(Session session) throws HibernateException {
           5               checkWriteOperationAllowed(session);
           6               session.saveOrUpdate(entity);
           7               return null;
           8          }

           9     }
          true);
          10}

          11

          4)   核心的實現就在HibernateTemplate里面。篇幅原因,我就不Copy全部的代碼了


          1public Object execute(HibernateCallback action, boolean exposeNativeSession) throws DataAccessException {
          2
          3}

          4


          這里,幫你做了SessionTransaction的封裝。讓你可以免去煩瑣無謂的try catch finally 和相關操作。在Spring中基本上采用容器處理事務。這樣在事務的處理上也達到了統一性。    

              到這里,感覺還不錯吧? 要是你沒有打算使用Spring呢?這種優勢不就沒有了嗎?那到未必,既然都有得“抄襲”拉!就自己弄一個吧!

           

          自己實現一個功能相當的模板

          不容易描述清楚,就用簡單的代碼來說明吧。

           

           1package com.goingmm.test;
           2import org.hibernate.HibernateException;
           3import org.hibernate.Session;
           4import org.hibernate.SessionFactory;
           5import org.hibernate.Transaction;
           6import org.hibernate.cfg.Configuration;
           7// HibernateTemplate 來集中處理 Session和Transaction
           8
           9public class HibernateTemplate {
          10     public static SessionFactory sessionFactory = null;
          11public void perform(HibernateCallback callback) {
          12         Session session = null;
          13         Transaction tx = null;
          14         try {
          15              if (sessionFactory != null)
          16                   session = sessionFactory.openSession();
          17              else
          18                   session = initSessionFactory().openSession();
          19              tx = session.beginTransaction();
          20// 把對象納入Hibernate管理是在execute里面實現的
          21              callback.execute(session);
          22              session.flush();
          23              tx.commit();
          24         }
           catch (HibernateException e) {
          25              try {
          26                   tx.rollback();
          27              }
           catch (Throwable t) {
          28              }

          29              throw new RuntimeException(e);
          30         }
           finally {
          31              try {
          32                   if(session != null)
          33session.close();
          34              }
           catch (HibernateException ex) {
          35                   throw new RuntimeException(ex);
          36              }

          37         }

          38     }

          39// 建議用一個Servlet,在應用開始的時候Call一次 來初始化SessionFactory
          40     public static SessionFactory initSessionFactory() {
          41         Configuration config = new Configuration().configure();
          42         sessionFactory = config.buildSessionFactory();
          43         return sessionFactory;
          44     }

          45}

          46



           

          1package com.goingmm.test;
          2import org.hibernate.HibernateException;
          3import org.hibernate.Session;
          4public interface HibernateCallback {
          5     void execute(Session session) throws HibernateException;
          6}

          7
          8 
          9

           

           1package com.goingmm.test;
           2import org.hibernate.HibernateException;
           3import org.hibernate.Session;
           4
           5public class PersonHibernateDao implements IDAO{
           6public void create(final Object person) {
           7// 這里使用了匿名內部類 來實現execute
           8new HibernateTemplate().perform(new HibernateCallback(){
           9              public void execute(Session session) throws HibernateException {
          10//標題不是說Session要撤離嗎?    這里撤離了,就等于沒有使用Hibernate 呵呵!
          11session.save(person); 
          12         }

          13     }
          );
          14     }

          15}

          16

           

           1package com.goingmm.test;
           2import com.goingmm.bean.Person;
           3public class UseHibernateTemplateTest{
           4     public static void main(String[] args) {
           5         IDAO dao = new PersonHibernateDao();
           6         Person person = new Person();
           7         person.setPersonName("IBM");
           8         person.setPersonEmai("goingmm@gmail.com");
           9         person.setPersonSex("M");
          10         dao.create(person);
          11     }

          12}

          13


               上面的DAO實現還有代碼風格都不推薦大家學習。實現一個優秀的DAO框架沒這么簡單。這種做法我沒有在真實項目中檢驗過,不確定,會不會有其他問題。因為這里我只是為了簡單的表述HibernateTemplate思想的實現。只要理解了這種思想,相信你能寫出更好更完美的實現。如果有更好的主意或者建議請Email告訴我。

           

          其他可借鑒的實現

               《深入淺出Hibernate》采用hibernatesynchronizer生成基礎代碼的方式,架構自己的持久層。作者自己實現了一個相似功能的HibernateTemplateHibernateCallback接口。有興趣的話可以去研究一下。

               這種能直接生成基礎代碼的方式很不錯。比起Spring我還是覺得麻煩了很多。而且我也還沒時間去全面玩這個插件(據說,有提供一些成熟的模板方式生成,我只玩過默認的生成方式)。

              

          2005-12-6 SCSCHINA New Office


          posted on 2005-12-07 13:55 Goingmm 閱讀(1691) 評論(11)  編輯  收藏 所屬分類: Reading Note

          評論

          # re: Session和Transaction安全撤離現場 2005-12-07 14:37 sanmans
          shafa  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-07 15:17 sofaer
          sofa  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-07 15:20 sofaer
          原來不是沙發了哈,你最近在看《深入淺出Hibernate》嗎?  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-07 16:12 sanmans
          public class PersonHibernateDao implements IDAO{}
          IDAO舍不得拿來看索!  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-08 16:02 todogoingmm
          SORRY Sanmans... 沒什么神秘的,忘記了貼出來
          public interface IDAO {
          public void create(final Object obj);
          }
          我只是隨便放的一個方法,關于DAO的結構,勿模仿
          最近在看《深入淺出Hibernate》?
          沒有,最近想看看書,但是總靜不下來
          上次去北京前看了這本書的部分,內容和作者發布的免費文檔差不多  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-09 16:14 jigsaw
          am wondering what's the core value of web app...
          is there any experience/knowledge can make you irreplaceable?
          none!
          anyone can read through the docs/books and get familiar with those frameworks after a few real projects -- all these wont take
          more than 2 yrs
          and after reading piles of *best practice*, *tips & traps*, etc., all you can do is to follow those styles, to obey those rules....it has nothing to do with innovation
          err...so what tech can make you unique? hmmm...pls tell me if you figure it out someday....=P

          anyway, u did a good job of inroduction to template pattern in persistance. what make sence is that you did it in ur own way.  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-12 14:06 9527
          呵呵,典型的先抑后揚。我有個朋友在研究非馮諾依曼計算機,XQL有沒有興趣參加科研啊?瓦卡卡。。。  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-12 14:39 todogoingmm
          無意間了解了,眼下不被大眾看好的ERP市場.
          http://tech.sina.com.cn/it/2005-11-16/1120767283.shtml

          不知道“新世界”有沒有實力徹底壟斷ERP市場。說不清楚這種趨勢下ERP的未來是混亂還是規范。
          當然,引用ERP只是從一個側面去看待問題。做J2EE將近兩年時間了。也沒有太多時間去考慮行業,技術的未來。本著自己僅有的興趣在“混飯吃”。J2EE的發展趨勢必然是一天比一天規范。有時候傻傻的想,以后做軟件可能就像寫WORD文檔。
          3G 即將到來,離我們最近的分水嶺-J2ME。曖昧的在誘惑著我。有個朋友說得有道理,在中國想發財得賺小錢,賺13億人每人一塊。這輩子就夠了。

          人的本能。求變總是在求存之后。
          -- J2EE小資  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-12 14:43 9527
          兄弟們,拼命掙錢吧,不過一定要開心哦。  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-13 15:29 jigsaw
          j2me? trust me, it's rubbish  回復  更多評論
            

          # re: Session和Transaction安全撤離現場 2005-12-13 15:49 jigsaw
          3G好像是不錯。。。不過非馮諾伊曼那個。。。等下輩子吧。。。  回復  更多評論
            

          主站蜘蛛池模板: 都安| 龙川县| 石泉县| 萝北县| 遵义市| 沛县| 封丘县| 隆昌县| 阿坝县| 商南县| 布尔津县| 尚义县| 贺兰县| 出国| 东兴市| 东明县| 青阳县| 辽宁省| 文山县| 花垣县| 肃北| 京山县| 武邑县| 嘉禾县| 灵寿县| 上栗县| 隆德县| 克什克腾旗| 于都县| 吴堡县| 河北省| 灌云县| 萍乡市| 肥城市| 呈贡县| 佛坪县| 罗甸县| 贵州省| 绥宁县| 长岛县| 杨浦区|