zoukankan      html  css  js  c++  java
  • [转]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。
     

  • 相关阅读:
    tp3.2和tp5的区别
    tp(调试模式,空操作,跨控制器调用,跨方法跳转--redirect(),框架语法,创建model模型)
    tp 连表查 分页 模糊查询
    thinkphp if和eq的区别
    js 面向对象例子
    JS字符串转换为JSON的四种方法笔记
    json在php中的使用之如何转换json为数组
    window.frames用法
    php js 数组排序
    控件常用
  • 原文地址:https://www.cnblogs.com/abinxm/p/2207352.html
Copyright © 2011-2022 走看看