Hibernate做爲和數據庫數據打交道的框架,天然會設計到操做數據的效率wenti,而對於一些頻繁操做的數據,緩存策略就是提升其性能一種重要手段,而Hibernate框架是支持緩存的,並且支持一級和二級兩種緩存,合理的使用緩存策略能夠大大提升咱們的操做數據效率,可是利用不能,可能會形成沒必要要的麻煩。 web
一,一級緩存(Session緩存): spring
Session緩存表示將查詢結果放置到Session的臨時存儲空間(一級緩存中)。Hibernate框架默認支持一級緩存的。一級緩存的範圍較小,一旦Session關閉,那麼緩存失效。咱們使用框架的各類方法,例如:get,load,save,update,delete等都支持一級緩存的。 數據庫
二,二級緩存(SessionFactory緩存): 編程
1,概述:二級緩存其實就是將查詢的數據放置在SessionFactory臨時存儲空間中,由於一個SessionFactory能夠建立多個Session對象,因此範圍比Session緩存的要大,多個Session能夠共享二級緩存的數據。固然了二級緩存也不能存儲大量的數據,這個要根據咱們電腦配置進行設置。 緩存
2,如何設置使用二級緩存呢?Hibernate默認是不支持二級緩存的。 安全
a,首先在hibernate.cfg.xml配置文件中添加屬性標籤,啓用二級緩存: 服務器
<!--啓用二級緩存 --> session
<propertyname="hibernate.cache.use_second_level_cache">true</property> app
b,二級緩存須要使用額外的第三方組件:ehcache。須要咱們拷入對應的jar包,以及將對應的ehcache.xml存放到src目錄下。在這個配置文件中,咱們能夠設置二級緩存的大小等。 框架
c,讓框架識別添加入的ehcache緩存組件,在hibernate.cfg.xml配置文件中添加屬性標籤:
<!--讓框架識別ehcache緩存組件 -->
<propertyname="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
d,設置須要緩存的映射類,這裏只是將一些查詢操做比較頻繁的類指定便可,哪些不常常操做的數據,是沒有必要利用緩存的。這裏例如:
<!-- 將指定的類存放到二級緩存中,其中read-only是指放入緩存的數據是隻讀的-->
<class-cache usage="read-only" class="com.ljh.hibernate.pojo.Student"/>
3,緩存的操做數據原理:
查詢數據時,會首先從一級緩存中取數據,若是取上,則直接使用,不然到二級緩存中取,若是取到則直接使用,不然,就會發送語句查詢數據庫。這樣利用一級和二級緩存會提升訪問效率。
固然使用二級緩存要慎重,要考慮數據的操做頻繁性,服務器的硬件配置,數據的安全性等等方面,這樣才能很好的利用二級緩存,提升咱們操做數據的效率,不然使用不當就會帶來沒必要要的麻煩。
三,Lazy(懶加載)
1,lazy(Hibernate的延遲加載功能):表示查詢當前對象或關聯對象數據時,不真正訪問數據庫,當使用對象非主鍵屬性時,才真正發送查詢語句,訪問數據庫。因爲在某些狀況下,查的數據在後續流程到可能用不上,若是作查詢處理就多餘了,因此延遲加載功能能夠提升性能,合理使用便可。固然了Hibernate框架是經過Cglib代理來完成延遲加載功能的擴展的。
2,用到lazy地方總結,這裏只是對類和映射的地方簡單總結了一下,在實際運用中咱們還要學會恰當的選擇:
標籤 |
起做用到什麼地方 |
取值解釋 |
<class> |
針對load方法 |
true : 延遲加載 (默認) false : 禁用延遲加載 |
<set> |
針對於一對多,多對多 |
true : 延遲加載 (默認) false : 禁用延遲加載 extra : 支持延遲加載,在訪問集合自身信息時能夠發送高效的查詢語句。(推薦) |
<many-to-one> |
針對於多對一,一對一 |
false : 禁用延遲加載 proxy : 延遲加載 (默認) no-proxy : 支持延遲加載,不使用cglbi代理的方式完成延遲加載。經過第三方的字節碼加強工具。 |
<one-to-one> |
針對一對一 |
和<many-to-one>標籤同樣,這裏須要注意: 一對一的主鍵關聯映射,根據主動方(不含外鍵)查詢被動方(既是主鍵,又是外鍵)時不支持延遲加載的。 |
3,遇到的wenti:lazy,延遲加載功能是運用的一級緩存,也就是利用的是session的內存,通常狀況下,咱們在用完session後會進行關閉,可是關閉後咱們就沒法進行延遲查詢數據了,也就是說,延遲加載功能就將失效,剖出異常:No Sesssion,因此這是須要咱們解決的。
4.NoSession異常的解決:
a,解決原理:咱們能夠在dao層不進行session的關閉,經過前邊學習的AOP編程思想,添加過濾器,在視圖層進行數據取完畢後進行關閉session,這樣就能夠解決了NoSession異常了。可是怎麼獲取呢?這裏又想到了前邊學習的ThreadLocal,咱們能夠將Session對象放到Threadlocal對象中,和線程進行綁定,到視圖層再經過ThreadLocal進行獲取關閉便可。
b,解決方案,AOP編程思想,想必都想到了Spring框架了吧,的確,Spring框架提供了OpenSessionInViewFilter過濾器解決NoSession異常,這裏咱們只須要配置一下便可。在web.xml中進行此過濾器的配置便可:
<!-- 過濾器須要配置在Struts2框架過濾器前面,不然不起做用。 --> <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping
c,配置的順序wenti,應該將openSessionInViewFilter配置到Struts2的流程前邊,這是由於Filter執行順序是從上向下的,並且Struts2框架的執行流程基本上包含了整個項目順序的所有流程,MVC流程框架麼,就體如今這裏了。配置到Struts2框架的流程後邊的過濾器是起不到做用的。
這些是Hibernate框架中重要的知識,咱們能夠經過合理使用緩存和lazy機制,使咱們的程序變得性能更增強,考慮優化項目時,這兩項是必需要考慮的。這些東西看起來是比較虛的內容,還須要咱們經過一些小例子和實際應用加深理解。