隨筆-9  評論-168  文章-266  trackbacks-0
          DAO開發

          注:
          (1)以下兩者都需在Spring XML配置文件中,注冊Bean(實現類)來依賴注入SessionFactory.
          (2.1)Spring 中進行事務管理的通常方式是利用AOP(面向切片編程)的方式,為普通java類封裝事務控制,它是通過動態代理實現的,由于接口是
                  延遲實例化的, spring在這段時間內通過攔截器,加載事務切片。原理就是這樣,具體細節請參考jdk中有關動態代理的文檔。本文主要講解
                  如何在spring中進行事務控制。
          (2.2)動態代理的一個重要特征是,它是針對接口的,所以我們的DAO要通過動態代理來讓spring接管事務,就必須在DAO前面抽象出一個接口.  當然
                 如果沒有這樣的接口,那么spring會使用CGLIB來解決問題,但這不是spring推薦的方式.

          (一)直接使用Hibernate API (不推薦使用)
          public class DaoImp implate Dao{
                   private SessionFactory sessionFactory;
                   private static String hql = "from User u where u.username=? ";

                    public void setSessionFactory(SessionFactory sessionFactory){
                              this.sessionFactory=sessionFactory;
                    }

                     public boolean isValidUser(String username) { 
                          try{
                               List userList = sessionFactory.getCurrentSession().creatQuery(hql).setParameter(0,username).list();
                               if (userList.size() > 0) {
                               return true; 
                           } catch (HibernateException ex){
                               throw converHibernaterAccessException(ex);
                            }   
                       } 
          }
           
          優點:與Spring框架完全分離
          缺點:(1)無法使用Spring框架封裝所提供的額外功能.如,直接使用Hibernate API 需用try...catch()處理HibernateException異常.
                   (2)需在實現類中加入setSessionFactory(SessionFactory sessionFactory)屬性,接收依賴注入的SessionFactory.

          (二)繼承 Spring 的 HibernateDaoSupport 使用 HibernateTemplate (不推薦使用getSession())
          public class DaoImp extend HibernateDaoSupport implates Dao{
                   //private SessionFactory sessionFactory;
                   private static String hql = "from User u where u.username=? ";

                    //public void setSessionFactory(SessionFactory sessionFactory){
                    //          this.sessionFactory=sessionFactory;
                    //}


                     public boolean isValidUser(String username) { 
                        //  try{
                        //     List userList = sessionFactory.getCurrentSession().creatQuery(hql).setParameter(0,username).list(); 

                               List userList = getHibernateTemplate().find(hql,username); 
                               if (userList.size() > 0) {
                               return true; 
                         // } catch (HibernateException ex){
                        //     throw converHibernaterAccessException(ex);
                       //  }  
           
                       }
           
                     public boolean isValidUser(String username,String password) throw DataAccessException { 
                               Session session = getSession();                 //不推薦使用,用完后需手動關閉
                               String[] userlist=new String[2];
                               userlist[0]=username;
                               userlist[1]=password;
                           try{
                               List userList = session.find(hql,userlist);       //Hibernate語句; 
                               session.close();
                               if (userList.size() > 0) {
                               return true; 
                            } catch (HibernateException ex){
                               throw converHibernaterAccessException(ex);
                            }   
                       } 
          }

          特點:對HibernateTemplate沒有提供的功能,可以直接調用HibernateDaoSuppor對象的getSession()方法(極其不推薦使用)得到Session對象實例用try{ Hibernate API }catch (HibernateException ex )操作.

          (三)對 HibernateTemplate 沒有提供的功能, 還可以用HibernateCallback 回調的方法管理數據庫. (極其推薦)

           /**
            * 使用 hql 語句進行操作
            * @param hql       HSQL 查詢語句
            * @param offset   開始取數據的下標
            * @param length   讀取數據記錄數
            * @return List       結果集
            */
           public List getListForPage ( final String hql , final int offset , final int length ) {

               List list = getHibernateTemplate().executeFind ( new HibernateCallback ( ) {
                     public Object doInHibernate ( Session session ) throws HibernateException, SQLException {
                               Query query = session.createQuery ( hql ) ;
                               query.setFirstResult ( offset ) ;
                               query.setMaxResults ( length ) ;
                               List list = query.list ( ) ;
                               return list ;
                     }
              }) ;
              return list ;
           }


          //---------------------------------------------------------------------------

          final String queryString = "from Fourm";                 //必須定義final類型
             List l= getHibernateTemplate().executeFind(new HibernateCallback(){
              public Object doInHibernate ( Session session ) throws HibernateException, SQLException {
                              Query query = session.createQuery ( queryString ) ;
                              query.setFirstResult ( 0 ) ;
                              query.setMaxResults ( 10 ) ;
                              List list = query.list ( ) ;
                              return list ;
                    }

          //------------------------------------------------------------



          為什么不使用getSession(),而使用回調的詳細說明:

          紫蝶∏飛揚↗
          聽個SPRING+HIBERNATE開發的問題.
          SPRING想調用HIBERNATE的方法有兩種,一種是使用getSession();一種是:HibernateCallback回調.
          他們有什么不同?
          海綿♂寶寶
          前者沒有事務管控,Spring把Hibernate最原始的Session給你!但是它不被聲明式事務管理的服務!
          紫蝶∏飛揚↗
          ...聲明式事務不會對他進行事務管理?
          海綿♂寶寶
          后者也是把Session返給你,但是通過閉包回調的形式給你使用,Spring會在給你之前做一下手腳,例如:添加聲明式事務管理中聲明的事務屬性!
          海綿♂寶寶
          因為你寫的方法通過匿名函數閉包,然后由Spring去負責執行閉包體內的方法!
          海綿♂寶寶
          Java里的借口回調基本都是借用匿名內部類實現的閉包!
          海綿♂寶寶
          你看一下Spring的HibernateDaoSupport的源代碼就知道運行過程了!
          海綿♂寶寶
          直接使用getSession()還不享有Spring提供的模板支持,也就是說你得手動關閉連接,否則會一直掛在那兒,直到超時連接池才會回收這個連接!
          海綿♂寶寶
          這樣很容器連接池連接數量溢出!你懂了啊?
          紫蝶∏飛揚↗
          嗯.
          紫蝶∏飛揚↗
          new HibernateCallback(){
              public Object doInHibernate ( Session session ) throws HibernateException, SQLException {
          必須這樣的方式嗎?
          海綿♂寶寶
          建議補習一下編程中的閉包、回調的知識,再看看Spring的那段代碼就可以徹底理解了!
          海綿♂寶寶
          恩!
          紫蝶∏飛揚↗
          哦.明白了.
          海綿♂寶寶
          如果你覺得getHibernateTemplate()提供的方法不足以滿足你的要求!你就得這么使用!
          紫蝶∏飛揚↗
          明白.不夠用的情況下用回調.
          海綿♂寶寶
          閉包JavaScript支持的比較好,因為它是以函數為單元的,Java過于強調面向對象,所以只能用匿名內部類來有限的支持閉包!標準的回調都是方法回調,也就是閉包到方法中,而不是類中!所以Java中的閉包和其他的語言有一些區別的,例如訪問外部變量必須是final的!
          海綿♂寶寶
          據說JDK1.7會加入對函數閉包調用的支持!
          紫蝶∏飛揚↗
          ...歷害.
          紫蝶∏飛揚↗
          偶只知道這樣用,不知道為什么這樣用.
          海綿♂寶寶
          那可不行啊!呵呵!我最一開始也不大明白,后來仔細研究了閉包、回調的知識就懂了!
          其實這種用法在Swing編程里天天都用啊!把一個匿名的監聽器實現類注冊到事件源,只不過那個時候沒有注意到這是閉包和回調罷了!
          紫蝶∏飛揚↗
          看來有時間得好好看看了...

          posted on 2007-11-23 11:30 紫蝶∏飛揚↗ 閱讀(5987) 評論(0)  編輯  收藏 所屬分類: SpringHibernate
          主站蜘蛛池模板: 且末县| 江口县| 东兰县| 腾冲县| 化隆| 乐安县| 宝坻区| 伊通| 霍邱县| 湘乡市| 佛坪县| 湟源县| 高阳县| 辽阳县| 汾阳市| 二连浩特市| 汉阴县| 贵阳市| 台江县| 汝州市| 怀集县| 枝江市| 兰西县| 时尚| 渝北区| 武义县| 和平区| 钟祥市| 神池县| 文山县| 上虞市| 扎赉特旗| 阆中市| 巴彦县| 社旗县| 海原县| 宁河县| 浦江县| 天长市| 彭泽县| 临安市|