• [转]Hibernate Gossip: 簡介快取(Session Level)


    转自:http://caterpillar.onlyfun.net/Gossip/HibernateGossip/SessionLevelCache.html

    資料庫每一次的查詢都是一次不小的開銷,例如連結的開啟、執行查詢指令,當資料庫與應用伺服器不在同一個伺服器上時,還必須有遠程調用、Socket的建 立等開銷,在Hibernate這樣的ORM框架中,還有資料的封裝等開銷必須考慮進去。

    快取(Cache)是資料庫在記憶體中的臨時容器,從資料庫中讀取的資料在快取中會有一份臨時拷貝,當您查詢某個數據時,會先在快取中尋找是否有相對應的 拷貝,如果有的話就直接返回資料,而無需連接資料庫進行查詢,只有在快取中找不到資料時,才從資料庫中查詢資料,藉由快取,可以提昇應用程式讀取資料時的 效能。

    對於Hibernate這樣的ORM框架來說,快取的機制更形重要,在Hibernate中快取分作兩個層級:Session level與SessionFactory level(又稱Second level快取)。

    這邊先介紹Session level的快取,在Hibernate中Session level快取會在使用主鍵載入資料或是延遲初始(Lazy Initialization) 時作用,Session level的快取隨著Session建立時建立,而Session銷毀時銷毀。

    Session會維護一個Map容器,並保留與目前Session發生關係的資料,當您透過主鍵來載入資料時,Session會先依據所要載入的類別與所 給定的主鍵,看看Map中是否已有資料,如果有的話就返回,若沒有就對資料庫進行查詢,並在載入資料後在Map中維護。

    可以透過==來比較兩個名稱是否參考至同一個物件,以檢驗這個事實:

    Session session = sessionFactory.openSession();
    User user1 = (User) session.load(User.class, new Integer(1));
    User user2 = (User) session.load(User.class, new Integer(1));
    System.out.println(user1 == user2);
    session.close();

    第二次查詢資料時,由於在快取中找到資料物件,於是直接返回,這與第一次查詢到的資料物件是同一個實例,所以會顯示true的結果。

    可以透過evict()將某個物件從快取中移去,例如:
    Session session = sessionFactory.openSession();
    User user1 = (User) session.load(User.class, new Integer(1));
    session.evict(user1);
    User user2 = (User) session.load(User.class, new Integer(1));
    System.out.println(user1 == user2);
    session.close();

    由於user1所參考的物件被從快取中移去了,在下一次查詢時,Session在Map容器中找不到對應的資料,於是重新查詢資料庫並再封裝一個物件,所 以user1與user2參考的是不同的物件,結果會顯示false。

    也可以使用clear()清除快取中的所有物件,例如:
    Session session = sessionFactory.openSession();
    User user1 = (User) session.load(User.class, new Integer(1));
    session.clear();
    User user2 = (User) session.load(User.class, new Integer(1));
    System.out.println(user1 == user2);
    session.close();

    同樣的道理,這次也會顯示false。

    Session level的快取隨著Session建立與銷毀,看看下面這個程式片段:
    Session session1 = sessionFactory.openSession(); 
    User user1 = (User) session1.load(User.class, new new Integer(1)); 
    session1.close(); 

    Session session2 = sessionFactory.openSession(); 
    User user2 = (User)session2.load(User.class, new Integer(1)); 
    session2.close(); 

    System.out.println(user1 == user2);

    第一個Session在關閉後,快取也關閉了,在第二個Session的查詢中並無法用到第一個Session的快取,兩個Session階段所查詢到的 並不是同一個物件,結果會顯示false。

    在載入大量資料時,Session level 快取的內容會太多,記得要自行執行clear()清除快取或是用evict()移去不使用物件,以釋放快取所佔據的資源。

    您也可以使用Session的setReadOnly(object, true),設定某物件為唯讀,對於唯讀資料,不會在快取中維護一個複本,不會執行dirty check。
     

  • 相关阅读:
    [CSS] Showing horizontal scrollbar always for the table
    [Angular Unit Testing] Testing Component methods
    [Angular Unit Testing] Testing Services with dependencies
    Win7下unetbootin-windows-585工具制作Ubuntu12.04 U盘启动盘
    一个外行谈移动互联网产品的生与死
    unity 距离某天还有多久
    UI线程与worker线程
    关于 unity3d securityexception no valid crossdomain policy available 的错误解决方法
    小窍门:变更Windows Azure Websites自带的node.exe版本
    Windows SVN变更发送邮件通知(JAVA实现)
  • 原文地址:https://www.cnblogs.com/abinxm/p/2207352.html
Copyright © 2020-2023  润新知