Hibernate二級緩存

  • 一級緩存:session級別緩存,一次請求中共享數據
session就是連接,有很多的session,併發時沒人一個session。

所以一個session一個一級緩存

默認就存在
所以session就是線程級別的,每個session都有自己的緩存
  • 二級緩存:
二級緩存就一個:
    SessionFactory

    不是默認就有的
所以是進程級別的
    也是在內存中

那麼什麼數據放在二級緩存中?

1.經常使用的數據

2.不經常被修改

以上兩點需要同時滿足
那麼爲什麼呢?
因爲多個session同時訪問,出現併發問題。
使用二級緩存的好處?
1.提高訪問數據的速度。
2.不用通過網絡獲取數據,節省網絡資源
例如:
買票:省,市,縣

    如果是Android用xml解析
    那麼web端,滿足以上兩個要求,就可以放在二級緩存中。

二級緩存提供商

我們在這裏使用ehcache

導入jar包
然後

<!-- 開啓二級緩存-->
//hibernate.properties

//hibernate.cache.use_second_level_cache=true
<!--配置使用二級緩存-->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EHCacheProvider</property>
類緩存區、集合緩存區、查詢緩存區、時間戳緩存區
類緩存區:放入查詢的對象


1.先配置
    <!--配置類緩存區緩存的類類型,放在mapping之後-->
    <class-cache usage="read-only" class="domain.Customer"/>


//test.java

session.get(Customer.class,1);
//會發送select到數據庫,查詢出的數據被封裝成對象放入一級緩存,
//還會放入二級緩存

session.clear()//清空一級緩存

session.get(Customer.class,1);
//我們在這裏查看有沒有打印select語句,如果沒有,說明從二級緩存中取得數據

從debug可以看出,沒有輸出select語句,那麼說明是從二級緩存中取得數據


清空一級緩存後在從緩存中取,應該是同一個對象,理論上應該輸出true

其實真實情況是:
    輸出爲false,說明了類緩存區,存的不是整個對象,存的是對象的散列數據
    當我們查詢時,取出數據,再封裝成新的對象。所以這時候,兩個對象不一樣了。


另外:每次session.clear();  
    清空的是上一步的一級緩存,如果再get,就又生成新的一級緩存
集合緩存區:
<!--需要配置Order類-->
<class-cache usage="read-only" class="domain.Order"/>
<!--配置集合緩存區緩存的集合-->
<collection-cache usage="read-only" collection="Customer.orders"></>
//test.java

session.get(Customer.class,1);
//注意:默認關聯訂單是懶加載,所以不會查詢   
//先使用一下
for(Order order:cus.getOrders()){
    System.out.print(order.getName());
}
session.clear();

//從類緩存區中取
get(Customer.class,1);
//從集合緩存區取
for(Order order:cus.getOrders()){
    System.out.print(order.getName());
}

通過debug看出直接從二級緩存中取,沒有發送select

那麼集合緩存區怎麼存的集合?
我們先把 <class-cache  order  這個配置去掉

然後通過迭代器遍歷,

Iterator<Order> ite = cus.getOrders().iterator();
//當執行到這一步,又重新發送了select語句
//並且是通過orderid查的

這說明集合緩存區緩存的是訂單id
那麼正常的執行步驟應該是這樣的:
當使用時,先拿id去類緩存區查找,如果沒找到,
再去數據庫根據訂單id查詢

查詢緩存區:hql使用的緩存區

配置過程:

//1.開啓查詢緩存區
<property name="hibernate.cache.use_query_cache">true</property>
//test.java
Query query = session.createQuery("from Customer");
query.setCacheable(true);//使用二級緩存
List<Customer> list = query.list();
數據放入了類緩存區,查詢緩存區還是存儲id
時間戳緩存區
最後操作時間
t_customer 2016-10-10 12.12.12
那麼這有什麼用?
比如說我們先查詢:
    cus = ...
    //time1

    session.createQuery("update t_customer set name="wang" where id=8");
    session.clear();
    cus = ...
    //當我們再查詢時,緩存中數據就不是當前數據了
    //檢查時間戳,
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章