緩存是介於物理數據源與應用程序之間,是對數據庫中的數據複製一份臨時放在內存中的容器,其做用是爲了減小應用程序對物理數據源訪問的次數,從而提升了應用程序的運行性能。Hibernate在進行讀取數據的時候,根據緩存機制在相應的緩存中查詢,若是在緩存中找到了須要的數據(咱們把這稱作「緩存命 中"),則就直接把命中的數據做爲結果加以利用,避免了大量發送SQL語句到數據庫查詢的性能損耗。html
hibernate緩存:java
(1)一級緩存(又稱做事務緩存,是hibernate內置的,不能卸除)就是Session級別的緩存,一個Session作了一個查詢操做,它會把這個操做的結果放在一級緩存中,若是短期內這個數據庫
session(必定要同一個session)又作了同一個操做,那麼hibernate直接從一級緩存中拿,而不會再去連數據庫,取數據; 緩存的生命週期依賴於Session的生命週期,當Session被關閉後,緩存也就結束生命週期。緩存
(2)二級緩存就是SessionFactory級別的緩存,顧名思義,就是查詢的時候會把查詢結果緩存到二級緩存中,若是同一個sessionFactory建立的某個session執行了相同的操做,hibernate就會從二級緩存中拿結果,而不會再去鏈接數據庫;session
(3)Hibernate中提供了兩級Cache,第一級別的緩存是Session級別的緩存,它是屬於事務範圍的緩存。這一級別的緩存由hibernate管理併發
的,通常狀況下無需進行干預;第二級別的緩存是SessionFactory級別的緩存,它是屬於進程範圍或羣集範圍的緩存。這一級別的緩app
存能夠進行配置和更改,而且能夠動態加載和卸載。 Hibernate還爲查詢結果提供了一個查詢緩存,它依賴於第二級緩存;框架
一級緩存的操做:dom
1. save()。當session對象調用save()方法保存一個對象後,該對象會被放入到session的緩存中。ide
2. get()和load()。當session對象調用get()或load()方法從數據庫取出一個對象後,該對象也會被放入到session的緩存中。
3. 使用HQL和QBC等從數據庫中查詢數據。
2. Hibernate二級緩存策略的通常過程以下:
1) 條件查詢的時候,老是發出一條select * from table_name where …. (選擇全部字段)這樣的SQL語句查詢數據庫,一次得到全部的數據對象。
2) 把得到的全部數據對象根據ID放入到第二級緩存中。
3) 當Hibernate根據ID訪問數據對象的時候,首先從Session一級緩存中查;查不到,若是配置了二級緩存,那麼從二級緩存中查;查不到,再查詢數據庫,把結果按照ID放入到緩存。
4) 刪除、更新、增長數據的時候,同時更新緩存。
Hibernate二級緩存策略,是針對於ID查詢的緩存策略,對於條件查詢則毫無做用。爲此,Hibernate提供了針對條件查詢的Query Cache。
5) 二級緩存的對象可能放在內存,也可能放在磁盤.
3. 什麼樣的數據適合存放到第二級緩存中?
1) 不多被修改的數據
2) 不是很重要的數據,容許出現偶爾併發的數據
3) 不會被併發訪問的數據
4) 參考數據,指的是供應用參考的常量數據,它的實例數目有限,它的實例會被許多其餘類的實例引用,實例極少或者歷來不會被修改。
4. 不適合存放到第二級緩存的數據?
1) 常常被修改的數據
2) 財務數據,絕對不容許出現併發
3) 與其餘應用共享的數據。
5. 經常使用的緩存插件 Hibernater二級緩存是一個插件,下面是幾種經常使用的緩存插件:
◆Ehcache:可做爲進程範圍的緩存,存放數據的物理介質能夠是內存或硬盤,對Hibernate的查詢緩存提供了支持。
◆OSCache:可做爲進程範圍的緩存,存放數據的物理介質能夠是內存或硬盤,提供了豐富的緩存數據過時策略,對Hibernate的查詢
緩存提供了支持。
◆SwarmCache:可做爲羣集範圍內的緩存,但不支持Hibernate的查詢緩存。
◆JBossCache:可做爲羣集範圍內的緩存,支持事務型併發訪問策略,對Hibernate的查詢緩存提供了支持。
6. 配置Hibernate二級緩存的主要步驟:
1) 選擇須要使用二級緩存的持久化類,設置它的命名緩存的併發訪問策略。這是最值得認真考慮的步驟。
2) 選擇合適的緩存插件,而後編輯該插件的配置文件。
<property name="hbm2ddl.auto">update</property> <!-- 啓動二級緩存 --> <property name="cache.use_second_level_cache">true</property> <!-- 指定使用哪一種二級緩存 --> <property name="cache.provider_class">org.hibernate.cache.OSCacheProvider</property> <mapping resource="com/hsp/domain/Department.hbm.xml" /> <mapping resource="com/hsp/domain/Student.hbm.xml" /> <!-- 指定哪一個domain啓用二級緩存 特別說明二級緩存策略: 1. read-only 2. read-write 3. nonstrict-read-write 4. transcational --> <class-cache usage="read-write"/>
3)能夠把oscache.properties文件放在 src目錄下,這樣你能夠指定放入二級緩存的對象capacity 大小. 默認1000
7.使用二級緩存:
// TODO Auto-generated method stub //經過獲取一個sesion,讓hibernate框架運行(config->加載hibernate.cfg.xml) Session s=null; Transaction tx=null; try { //咱們使用基礎模板來說解. s=HibernateUtil.openSession(); tx=s.beginTransaction(); //查詢45號學生 Student stu1=(Student) s.get(Student.class, 45);//45->一級緩存 System.out.println(stu1.getName()); tx.commit(); } catch (Exception e) { e.printStackTrace(); if(tx!=null){ tx.rollback(); } }finally{ if(s!=null && s.isOpen()){ s.close(); } } System.out.println("*********************************"); try { //咱們使用基礎模板來說解. s=HibernateUtil.openSession(); tx=s.beginTransaction(); //查詢45號學生 Student stu1=(Student) s.get(Student.class, 45); System.out.println(stu1.getName()); Student stu3=(Student) s.get(Student.class, 46); System.out.println(stu3.getName()); tx.commit(); } catch (Exception e) { e.printStackTrace(); if(tx!=null){ tx.rollback(); } }finally{ if(s!=null && s.isOpen()){ s.close(); } } //完成一個統計,統計的信息在Sessfactory //SessionFactory對象. Statistics statistics= HibernateUtil.getSessionFactory().getStatistics(); System.out.println(statistics); System.out.println("放入"+statistics.getSecondLevelCachePutCount()); System.out.println("命中"+statistics.getSecondLevelCacheHitCount()); System.out.println("錯過"+statistics.getSecondLevelCacheMissCount());
在配置了二級緩存後,請你們要注意能夠經過 Statistics,查看你的配置命中率高不高