標籤:c style class blog code java
一、與觸發器協同工作:
當Hibernate與資料庫的觸發器協同工作時,會出現以下兩類問題:
1、觸發器使Session緩衝中的資料和資料庫中的不一致:
出現此問題的原因是觸發器運行在資料庫內,它執行的操作對Session是透明的。
解決方案:在執行完包含有觸發器的操作之後,立刻調用Session的flush()和refresh()方法,迫使Session的緩衝與資料庫同步。
2、Session的update()方法盲目的激發觸發器:
這種情況主要發生在Session調用update()或saveOrUpdate()方法時,能夠使一個游離對象和Session關聯,此時由於緩衝中不存在該對象的快照,因此肯定會執行一次update語句,進而激發觸發器。如果該對象的屬性和資料庫中的資料一致,那麼該update語句就是多餘的。要避免此種情況,在<class>元素中設定select-before-update="true"即可。
二、利用攔截器產生審計日誌:暫不關注。
三、Hibernate事件處理機制:
Hibernate3的核心處理模組採用了“事件\監聽器”設計模式。
Session的大部分方法都會觸發特定事件,該事件由相應的監聽器來處理。
在org.hibernate.event包中提供了與Session的各個方法對應的事件類別及監聽器介面。
建立及註冊客戶化監聽器方法的一般步驟:
1、建立客戶化監聽器:
A、直接實現特定的監聽器介面。
B、繼承Hibernate提供的監聽器介面的基礎實作類別,比如org.hibernate.enent.def.AbstractSaveEventListner.
C、繼承Hibernate提供的監聽器介面的預設實作類別。比如org.hibernate.event.def.DefaultSaveEventListner.
2、註冊客戶化監聽器:2種方式
A、在Hibernate的設定檔hibernate.cfg.xml中靜態註冊。
?
| 1 2 3 |
<event type="load"> <listener class="mypack.MyLoadListener" /> </event> |
B、在程式中動態註冊:可以註冊多個。
?
| 1 2 3 |
Configuration cfg = new Configuration(); LoadEventListener[] listeners = {new MyLoadListener(),...}; cfg.getEventListeners().setLoadEventListeners(listeners); |
四、批量處理資料:
大量操作帶來的問題:
A、佔用大量記憶體,比如批次更新,需要把大量的對象先載入到記憶體中,然後一一更新。
B、執行的更新語句的數目太多。
因此,應該盡量避免在應用程式層進行大量操作,而應該在資料庫層直接進行大量操作。若要在應用程式層執行大量操作,有以下四種方式:
1、通過Session來進行大量操作:
此種做法是在處理完一個對象或一小批對象之後,立刻調用flush()方法清理緩衝,然後調用clear()方法清空緩衝。
需要注意:
合理設定hibernate.jdbc.batch_size屬性。
如果對象採用identity標識符產生器,則Hibernate無法再JDBC層進行批量插入操作。
進行大量操作時,建議關閉二級緩衝。
2、通過StatelessSession來進行大量操作:用法和Session類似。
3、通過HQL來進行大量操作:Query.executeUpdate()
4、直接通過JDBC API來進行大量操作:
五、使用中繼資料:
通過SessionFactory.getClassMetadata()和getCollectionMetadate()可以擷取相應的對象來操縱中繼資料。
六、執行預存程序:參見JDBC的方式。