Hibernate第十二篇【二級緩存介紹、緩存策略、查詢緩存、集合緩存】

Hibernate二級緩存介紹

前面咱們已經講解過了一級緩存,一級緩存也就是Session緩存,只在Session的範圍內有效…做用時間就在Session的做用域中,範圍比較小java

Hibernate爲咱們提供了二級緩存功能:二級緩存是基於應用程序的緩存,全部的Session均可以使用數據庫

  • Hibernate提供的二級緩存有默認的實現,且是一種可插配的緩存框架!若是用戶想用二級緩存,只須要在hibernate.cfg.xml中配置便可; 不想用,直接移除,不影響代碼。
  • 若是用戶以爲hibernate提供的框架框架很差用,本身能夠換其餘的緩存框架或本身實現緩存框架均可以

這裏寫圖片描述

Hibernate二級緩存:存儲的是經常使用的類緩存


配置二級緩存

既然二級緩存是Hibernate自帶的,那麼咱們能夠在hibernate.properties文件中找到對應的信息..markdown

這裏寫圖片描述

  • #hibernate.cache.use_second_level_cache false【二級緩存默認不開啓,須要手動開啓】
  • #hibernate.cache.use_query_cache true 【開啓查詢緩存】
  • ## choose a cache implementation 【二級緩存框架的實現】
  • #hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
  • #hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
  • hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider 默認實現
  • #hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
  • #hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
  • #hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider

經過配置文件咱們能夠發現,二級緩存默認是不開啓的,須要咱們手動開啓,如下步驟:session

  • 1)開啓二級緩存
  • 2)指定緩存框架
  • 3)指定哪些類加入二級緩存

開啓二級緩存

在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默認是沒有爲集合數據設置二級緩存的…所以仍是須要去讀寫數據庫的信息

接下來,咱們就看看把集合設置爲二級緩存是什麼作的:

  • 在hibernate.cgf.xml中配置對象中的集合爲二級緩存
<!-- 集合緩存[集合緩存的元素對象,也加加入二級緩存] -->
        <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>
  • 在使用程序查詢的時候,也要調用setCacheable()方法,設置爲查詢緩存。
@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();
    }
相關文章
相關標籤/搜索