前面咱們已經講解過了一級緩存,一級緩存也就是Session緩存,只在Session的範圍內有效…做用時間就在Session的做用域中,範圍比較小java
Hibernate爲咱們提供了二級緩存功能:二級緩存是基於應用程序的緩存,全部的Session均可以使用數據庫
Hibernate二級緩存:存儲的是經常使用的類緩存
既然二級緩存是Hibernate自帶的,那麼咱們能夠在hibernate.properties文件中找到對應的信息..markdown
經過配置文件咱們能夠發現,二級緩存默認是不開啓的,須要咱們手動開啓,如下步驟:session
在hibernate.cfg.xml文件中開啓二級緩存框架
<!-- a. 開啓二級緩存 --> <property name="hibernate.cache.use_second_level_cache">true</property>
指定Hibernate自帶的二級緩存框架就行了ide
<!-- b. 指定使用哪個緩存框架(默認提供的) --> <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<!-- c. 指定哪一些類,須要加入二級緩存 --> <class-cache usage="read-write" class="zhongfucheng.aa.Monkey"/> <class-cache usage="read-only" class="zhongfucheng.aa.Cat"/>
咱們知道一級緩存是Session的緩存,那麼咱們在測試二級緩存的時候使用兩個Session來測試就行了。若是第二個Session拿到的是緩存數據,那麼就證實二級緩存是有用的。測試
package zhongfucheng.aa; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; public class App5 { public static void main(String[] args) { //獲取加載配置管理類 Configuration configuration = new Configuration(); //加載類對應的映射文件! configuration.configure().addClass(Animal.class); //建立Session工廠對象 SessionFactory factory = configuration.buildSessionFactory(); //獲得Session對象 Session session1 = factory.openSession(); //使用Hibernate操做數據庫,都要開啓事務,獲得事務對象 Transaction transaction = session1.getTransaction(); //開啓事務 transaction.begin(); Monkey monkey = (Monkey) session1.get(Monkey.class,"40283f815be67f42015be67f43240001" ); System.out.println(monkey.getName()); System.out.println("-----------------------"); Session session2 = factory.openSession(); Transaction transaction2 = session2.getTransaction(); transaction2.begin(); Monkey monkey2 = (Monkey) session1.get(Monkey.class, "40283f815be67f42015be67f43240001"); System.out.println(monkey2.getName()); //提交事務 transaction.commit(); transaction2.commit(); //關閉Session session1.close(); session2.close(); } }
獲得的是緩存數據!ui
咱們在把Animal類放進二級緩存的時候,用法爲只讀spa
也就是說,只能讀取,不能寫入,咱們來看看寫入會怎麼樣:
monkey2.setName("小猴子");
拋出了異常….
usage的屬性有4種:
若是咱們在數據庫查詢的數據是集合…Hibernate默認是沒有爲集合數據設置二級緩存的…所以仍是須要去讀寫數據庫的信息
接下來,咱們就看看把集合設置爲二級緩存是什麼作的:
<!-- 集合緩存[集合緩存的元素對象,也加加入二級緩存] --> <collection-cache usage="read-write" collection="cn.itcast.b_second_cache.Dept.emps"/>
public void testCache() { Session session1 = sf.openSession(); session1.beginTransaction(); // a. 查詢一次 Dept dept = (Dept) session1.get(Dept.class, 10); dept.getEmps().size();// 集合 session1.getTransaction().commit(); session1.close(); System.out.println("------"); // 第二個session Session session2 = sf.openSession(); session2.beginTransaction(); // a. 查詢一次 dept = (Dept) session2.get(Dept.class, 10); // 二級緩存配置好; 這裏不查詢數據庫 dept.getEmps().size(); session2.getTransaction().commit(); session2.close(); }
list()和iterator()會把數據放在一級緩存,但一級緩存只在Session的做用域中有效…若是想要跨Session來使用,就要設置查詢緩存
咱們在配置文件中還看到了查詢緩存這麼一條配置..
#hibernate.cache.use_query_cache true 【開啓查詢緩存】
也就是說,默認的查詢數據是不放在二級緩存中的,若是咱們想要把查詢出來的數據放到二級緩存,就須要在配置文件中開啓
<!-- 開啓查詢緩存 --> <property name="hibernate.cache.use_query_cache">true</property>
@Test public void listCache() { Session session1 = sf.openSession(); session1.beginTransaction(); // HQL查詢 【setCacheable 指定從二級緩存找,或者是放入二級緩存】 Query q = session1.createQuery("from Dept").setCacheable(true); System.out.println(q.list()); session1.getTransaction().commit(); session1.close(); Session session2 = sf.openSession(); session2.beginTransaction(); q = session2.createQuery("from Dept").setCacheable(true); System.out.println(q.list()); // 不查詢數據庫: 須要開啓查詢緩存 session2.getTransaction().commit(); session2.close(); }