hibernate使用緩存減小對數據庫的訪問次數,從而提高hibernate的執行效率。hibernate中有兩種類型的緩存:一級緩存和二級緩存。html
Hibenate中一級緩存,也叫作session的緩存,當調用session的save/saveOrUpdate/get/load/list/iterator方法的時候,都會把對象放入session的緩存中。sql
一級緩存能夠在session範圍內減小數據庫的訪問次數,只在session範圍有效,session關閉,一級緩存失效。數據庫
session的緩存由hibernate維護, 用戶不能操做緩存內容; 若是想操做緩存內容,必須經過hibernate提供的evit/clear方法操做。緩存
特色:session
只在當前session範圍有效,做用時間短,效果不是特別明顯!框架
在短期內屢次操做數據庫,效果比較明顯!ide
list和iterator的區別spa
list:hibernate
一次把全部的記錄都查詢出來code
會放入緩存,但不會從緩存中獲取數據
Iterator:
N+1查詢; N表示全部的記錄總數,即會先發送一條語句查詢全部記錄的主鍵(1),再根據每個主鍵再去數據庫查詢(N)
會放入緩存,也會從緩存中取數據
public void test5()throws Exception{ Session session = sf.openSession(); session.beginTransaction(); User user = new User(); user.setUserName("林黛玉"); session.save(user); user.setUserName("嘉寶"); session.save(user); session.getTransaction().commit(); session.close(); }
因爲一級緩存的做用,user對象只會被保存一次。
Hibernate提供了基於應用程序級別的緩存, 能夠跨多個session,即不一樣的session均可以訪問緩存數據。 這個緩存也叫二級緩存。
Hibernate提供的二級緩存有默認的實現,且是一種可插配的緩存框架!若是用戶想用二級緩存,只須要在hibernate.cfg.xml中配置便可; 不想用,直接移除,不影響代碼。若是用戶以爲hibernate提供的框架框架很差用,本身能夠換其餘的緩存框架或本身實現緩存框架。
開啓二級緩存:
list() 默認狀況只會放入緩存,不會從一級緩存中取,配置查詢緩存,可讓list()查詢從二級緩存中取數據。
<!--開啓二級緩存--> <property name="hibernate.cache.use_second_level_cache">true</property> <!--指定使用的緩存框架--> <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property> <!--開啓查詢緩存--> <property name="hibernate.cache.use_query_cache">true</property>
指定須要二級緩存的類:
若是設置了集合緩存,集合所屬的元素對象也要放入二級緩存,即Employee。
<!--指定哪一些類須要加入二級緩存--> <class-cache class="com.juaner.department.Employee" usage="read-only"/> <class-cache class="com.juaner.department.Dept" usage="read-only"/> <!--集合緩存,集合所屬的類型也要放入二級緩存--> <collection-cache collection="com.juaner.department.Dept.emps" usage="read-only"/>
使用二級緩存:
若是設置了查詢緩存,須要手動設置setCacheable(true)。
@Test public void test1(){ Session session = sf.openSession(); session.beginTransaction(); //setCacheable 指定從二級緩存中找,或放入二級緩存,針對list不從一級緩存中取數據的狀況 //從緩存中讀數據,查詢條件必須一致 //緩存機制爲Map<條件,結果> Query query = session.createQuery("from Dept").setCacheable(true); System.out.println(query.list()); session.getTransaction().commit(); session.close(); Session session1 = sf.openSession(); session1.beginTransaction(); query = session1.createQuery("from Dept").setCacheable(true); System.out.println(query.list()); session1.getTransaction().commit(); session1.close(); }
get: 及時加載,只要調用get方法馬上向數據庫查詢
load:默認使用懶加載,當用到數據的時候才向數據庫查詢
當用到數據的時候才向數據庫查詢,這就是hibernate的懶加載特性。
lazy 值
true 使用懶加載
false 關閉懶加載
extra 在集合數據懶加載時候提高效率,在真正使用數據的時候才向數據庫發送查詢的sql,若是調用集合的size()/isEmpty()方法,只是統計,不真正查詢數據!
來源於:https://www.cnblogs.com/juaner767/p/5575076.html