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列相同的列來進行關聯的!