hibernate 的一些筆記

1.持久化對象:
      用hibernate持久化對象也就是將它保存在Session實例中:
           Configuration cgf=new Configuration();
           SessionFactory factory=cfg.buildSessionFactory();
           Event event=new Event(); //實例化一個類的對象
           Session session=factory.openSession();
           session.saveOrUpdate(event);
           session.flush();
           session.close();
      hibernate在存儲對象時,Session不會立即將其寫入數據庫;相反,Session將大量數據庫寫操作加入隊列,心最大限度地提高性能!

2.新手常遇到的一個問題:
       將相同的對象的兩個實例與同一個Session實例相關聯,導致NonUniqueObjectException異常:
        Session session=factory.openSession();
        Event firstEvent=(Event)session.load(Event.class,myEventId); //根據指定的ID加載一個實例
        Event secondEvent=new Event();
        secondEvent.setId(myEventId);
        session.save(secondEvent);
       拋出的異常的意思是說在同一個session中存在不唯一的兩個實例;以下的代碼則可以避免這個問題:
        Session session=factory.openSession();
        Event firstEvent=(Event)session.load(Event.class,myEventId); //根據指定的ID加載一個實例
        if(session.contains(firstEvent))  //如果session中有這個對象則將其逐出,而用session.clear()方法則可以清除Session緩存中的所有對象;
             session.evict(firstEvent);
        Event secondEvent=new Event();
        secondEvent.setId(myEventId);
        session.save(secondEvent);


3.hibernate支持3種連接池服務:C3P0,Apache DBCP和Proxool,在配置文件中以connection.provider_class屬性來聲明。

4.事務將很多操作組成一個工作單元。如果批處理中的任何一個操作失敗,之間的所有操作將撤銷,整個工作單元停止。
  hiberbate中有兩種事務,hibernate中默認使用JDBC事務,因爲它們是最常用的;而如果要使用JTA事務則需要在配置文件中進行設置:
         <property name="transaction.factory_class">
             org.hibernate.transaction.JTATransactionFactory
         </property>
         <property name="jta.UserTransaction">
             java:comp/UserTransaction
         </property>
使用JTA事務有何好處?如果有多個事務性資源,如一個數據庫和一個消息隊列,JTA事務將很有用。JTA事務讓你能夠像對待單個事務一樣對待多個事務。
如果試圖通過一個Session實例創建多個事務,所有操作都將加入到第一個事務中,如下:
  Transaction tx1=session.beginTransaction();
  Event event=new Event();
  session.saveOrUpdate(event);
  Transaction tx2=session.beginTransaction();
  Event event2=new Event();
  session.saveOrUpdate(event2);
  tx1.commit();
  tx2.commit();
這個例子首先創建一個新的事務。第二次session.beginTransaction()時,將返回第一個事務實例。session.saveOrUpdate(event2)提交第一個事務,tx1.commit()重新提交一個事務。

   雖然可以創建兩個事務,但實際上只使用一個事務。當然,這帶來了一個問題:假設有兩個應用線程使用一個Session對象。第一個用線程開始JTA事務,並添加對象,同時,使用同一個事務的第二個線程刪除一個對象,然後提交事務。這對第一個線程有什麼影響呢? 答案是第一個線程不會被提交! 這個答案可以猜到,不過這種問題難以調試,這也指出了一個要點:Session不應由多個應用線程同時使用。

5.hibernate有4種不同緩存服務,這在配置文件要用以下語句來聲明: EHCache,OSCache,SwarmCache,TreeCache
   <property name="cache.provider_class">org.hibernate.cache.四種中的一種</property>

  6.hibernate中的繼承
      hibernate爲了解決層次結構持久化中的問題,Hibernate支持3種不同的繼承持久化策略:
      a.每個類層次一個表;b.每個子類一個表;c.每個具體類一個表;

    (1)每個類層次一個表則是三種中最容易的使用的,類層次中的所有類都保存在一個表中。
   假設有一個基類Event和兩個子類ConferrenceEvent和NetWorkingEvent,它們的層次的映射定義程序清單如下:
     <class name="Event" table="events" discriminator-value="EVENT">
        <id name="id" type="long">
           <generator class="native" />
        </id>
        <discriminator colum="event_type" type="string" length="15"/>
        <subclass name="ConferrenceEvent" discriminator-value="CONF_EVENT">
            <property name="" colum="" />
              ...
        </subclass>
        <subclass name="NetworkingEvent" discriminator-value="NET_EVNET">
            <property name="" colum="" />
        </subclass>
     </class>
    個人理解:也就是說它們在同一個表中是通過discriminator這一列的值來進行認定具體對象是屬於哪一個類的! discriminator是 辨別者 的意思!還有的就是subclass標籤之間,可以包含如上等屬性元素,但不能包含有id元素和嵌套的subclass元素!

  (2)每個子類一個表
     將每個子類放在一個獨立的表中,這種方法不需要discriminator列,並建立了從子類表到基類表的一對一的映射;
     這種策略的映射定義如程序清單:
      <class name="Event" table="events">
          <id name="event_id" type="long">
              <generator class="native" />
          </id>
        <joined-subclass name="ConferrenceEvent" table="conf_events">
           <key column="event_id" />
        </joined-subclass>
         <joined-subclass name="NetworkingEvent" table="net_events">
           <key column="event_id" />
        </joined-subclass>
      </class>
     這種策略是通過在子類對應的表中定義與基類對應表的id列相同的列來進行關聯的!
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章