1. 程式人生 > >簡述Hibernate的快取和懶載入

簡述Hibernate的快取和懶載入

1.為什麼使用快取

  hibernate使用快取減少對資料庫的訪問次數,從而提升hibernate的執行效率。hibernate中有兩種型別的快取:一級快取和二級快取。

2.一級快取

  Hibenate中一級快取,也叫做session的快取,當呼叫session的save/saveOrUpdate/get/load/list/iterator方法的時候,都會把物件放入session的快取中。

  一級快取可以在session範圍內減少資料庫的訪問次數,只在session範圍有效,session關閉,一級快取失效。

  session的快取由hibernate維護, 使用者不能操作快取內容; 如果想操作快取內容,必須通過hibernate提供的evit/clear方法操作。

特點:

         只在當前session範圍有效,作用時間短,效果不是特別明顯!

         在短時間內多次操作資料庫,效果比較明顯!

list和iterator的區別

list:

一次把所有的記錄都查詢出來

會放入快取,但不會從快取中獲取資料

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物件只會被儲存一次。

3.二級快取

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();
    }

4.get和load

get: 及時載入,只要呼叫get方法立刻向資料庫查詢

load:預設使用懶載入,當用到資料的時候才向資料庫查詢

5.懶載入

  當用到資料的時候才向資料庫查詢,這就是hibernate的懶載入特性。

lazy 值

     true     使用懶載入

     false    關閉懶載入

     extra   在集合資料懶載入時候提升效率,在真正使用資料的時候才向資料庫傳送查詢的sql,如果呼叫集合的size()/isEmpty()方法,只是統計,不真正查詢資料!