您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Hibernate緩存機(jī)制的原理”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Hibernate緩存機(jī)制的原理”吧!
Hibernate是一個持久層框架,經(jīng)常訪問物理數(shù)據(jù)庫。
為了降低應(yīng)用程序?qū)ξ锢頂?shù)據(jù)源訪問的頻次,從而提高應(yīng)用程序的運(yùn)行性能。
緩存內(nèi)的數(shù)據(jù)是對物理數(shù)據(jù)源中的數(shù)據(jù)的復(fù)制,應(yīng)用程序在運(yùn)行時從緩存讀寫數(shù)據(jù),在特定的時刻或事件會同步緩存和物理數(shù)據(jù)源的數(shù)據(jù)。
回到頂部
當(dāng) Session 對象調(diào)用 save() 方法保存一個對象后,該對象會被放入到 Session 緩存中。
當(dāng) Session 對象調(diào)用 get() 或 load() 方法從數(shù)據(jù)庫取出一個對象后,該對象也會被放入到 Session 緩存中。
當(dāng)使用同一個 Session 編寫 HQL 和 QBC 等從數(shù)據(jù)庫中查詢數(shù)據(jù)時,將直接從緩存中讀取數(shù)據(jù),不會訪問數(shù)據(jù)庫。
Hibernate 提供了幾個方法(evit/clear/contains/flush....)來管理和判斷一級緩存。
現(xiàn) JavaEE Dao 層中,提供給外部的數(shù)據(jù)庫訪問,每次都會從 Session 工廠中獲取新的 Session 線程 ,導(dǎo)致一級緩存很少被利用。
實例項目源碼:https://git.oschina.net/LanboEx/hiberdemo
//1.Hibernate 自身的一級緩存,可以查看到只輸出了一條 sql Session session = getSession(); UserPO userPO = session.get(UserPO.class, "031e7a36972e11e6acede16e8241c0fe"); System.out.println("1. 第一次訪問 DB:" + userPO.getName() + "," + userPO.getPasswd()); UserPO userPO1 = session.get(UserPO.class, "031e7a36972e11e6acede16e8241c0fe"); System.out.println("2. 第二次訪問 DB:" + userPO1.getName() + ",一級緩存中是否存在特定對象" + session.contains(userPO));
//2.使用 evite/clear 方法手動清除緩存中特定對象,可以看到 hiber 輸出了兩條 SQL Session session1 = getSession(); UserPO userPO3 = session1.get(UserPO.class, "031e7a36972e11e6acede16e8241c0fe"); System.out.println("3. 第一次獲取對象:" + userPO3.getName() + "," + userPO3.getPasswd()); session1.evict(userPO3); UserPO userPO4 = session1.get(UserPO.class, "031e7a36972e11e6acede16e8241c0fe"); System.out.println("4. 第二次獲取對象:" + userPO4.getName() + "," + userPO4.getPasswd());
回到頂部
Hibernate 緩存包括兩大類:
a.Hibernate 一級緩存,又稱為[Session的緩存]。
Session 內(nèi)置不能被卸載,Session 的緩存是事務(wù)范圍的緩存(Session 對象的生命周期通常對應(yīng)一個數(shù)據(jù)庫事務(wù)或者一個應(yīng)用事務(wù))。
一級緩存中,持久化類的每個實例都具有唯一的 OID。
b.Hibernate 二級緩存,又稱為[SessionFactory的緩存]。
由于 SessionFactory 對象的生命周期和應(yīng)用程序的整個過程對應(yīng)。
Hibernate二級緩存是進(jìn)程范圍或者集群范圍的緩存,有可能出現(xiàn)并發(fā)問題,需要采用適當(dāng)?shù)牟l(fā)訪問策略,該策略為被緩存的數(shù)據(jù)提供了事務(wù)隔離級別。
第二級緩存是可選的,是一個可配置的插件,默認(rèn)下 SessionFactory 不會啟用這個插件。
Hibernate 提供了 org.hibernate.cache.CacheProvider 接口,它充當(dāng)緩存插件與 Hibernate 之間的適配器。
什么樣的數(shù)據(jù)適合存放到第二級緩存中?
1) 很少被修改的數(shù)據(jù)
2) 不是很重要的數(shù)據(jù),允許出現(xiàn)偶爾并發(fā)的數(shù)據(jù)
3) 不會被并發(fā)訪問的數(shù)據(jù)
4) 常量數(shù)據(jù)
不適合存放到第二級緩存的數(shù)據(jù)?
1) 經(jīng)常被修改的數(shù)據(jù)
2) 絕對不允許出現(xiàn)并發(fā)訪問的數(shù)據(jù),如財務(wù)數(shù)據(jù),絕對不允許出現(xiàn)并發(fā)
3) 與其他應(yīng)用共享的數(shù)據(jù)。
c.Session 的延遲加載實現(xiàn)要解決兩個問題:正常關(guān)閉連接和確保請求中訪問的是同一個 Session。
Hibernate Session 就是 java.sql.Connection 的一層高級封裝,一個 Session 對應(yīng)了一個 Connection。
Http 請求結(jié)束后正確的關(guān)閉 Session(過濾器實現(xiàn)了Session的正常關(guān)閉);
延遲加載必須保證是同一個 Session( Session 綁定在 ThreadLocal)。
d.Hibernate 查找對象如何應(yīng)用緩存?
當(dāng) Hibernate 根據(jù) ID 訪問數(shù)據(jù)對象的時候,首先從 Session 一級緩存中查;
查不到,如果配置了二級緩存,那么從二級緩存中查;
如果都查不到,再查詢數(shù)據(jù)庫,把結(jié)果按照 ID 放入到緩存刪除、更新、增加數(shù)據(jù)的時候,同時更新緩存。
e.一級緩存與二級緩存的對比圖
一級緩存 | 二級緩存 | |
存放數(shù)據(jù)的形式 | 相互關(guān)聯(lián)的持久化對象 | 對象的散裝數(shù)據(jù) |
緩存的范圍 | 事務(wù)范圍,每個事務(wù)都擁有單獨的一級緩存 | 進(jìn)程范圍或集群范圍,緩存被同一個進(jìn)程或集群范圍內(nèi)所有事務(wù)共享 |
并發(fā)訪問策略 | 由于每個事務(wù)都擁有單獨的一級緩存不會出現(xiàn)并發(fā)問題,因此無須提供并發(fā)訪問策略 | 由于多個事務(wù)會同時訪問二級緩存中的相同數(shù)據(jù),因此必須提供適當(dāng)?shù)牟l(fā)訪問策略,來保證特定的事務(wù)隔離級別 |
數(shù)據(jù)過期策略 | 處于一級緩存中的對象永遠(yuǎn)不會過期,除非應(yīng)用程序顯示清空或者清空特定對象 | 必須提供數(shù)據(jù)過期策略,如基于內(nèi)存的緩存中對象的最大數(shù)目,允許對象處于緩存中的最長時間,以及允許對象處于緩存中的最長空閑時間 |
物理介質(zhì) | 內(nèi)存 | 內(nèi)存和硬盤,對象的散裝數(shù)據(jù)首先存放到基于內(nèi)存的緩存中,當(dāng)內(nèi)存中對象的數(shù)目達(dá)到數(shù)據(jù)過期策略的maxElementsInMemory值,就會把其余的對象寫入基于硬盤的緩存中 |
緩存軟件實現(xiàn) | 在Hibernate的Session的實現(xiàn)中包含 | 由第三方提供,Hibernate僅提供了緩存適配器,用于把特定的緩存插件集成到Hibernate中 |
啟用緩存的方式 | 只要通過Session接口來執(zhí)行保存,更新,刪除,加載,查詢,Hibernate就會啟用一級緩存,對于批量操作,如不希望啟用一級緩存,直接通過JDBCAPI來執(zhí)行 | 用戶可以再單個類或類的單個集合的粒度上配置第二級緩存,如果類的實例被經(jīng)常讀,但很少被修改,就可以考慮使用二級緩存,只有為某個類或集合配置了二級緩存,Hibernate在運(yùn)行時才會把它的實例加入到二級緩存中 |
用戶管理緩存的方式 | 一級緩存的物理介質(zhì)為內(nèi)存,由于內(nèi)存的容量有限,必須通過恰當(dāng)?shù)臋z索策略和檢索方式來限制加載對象的數(shù)目,Session的evit()方法可以顯示的清空緩存中特定對象,但不推薦 | 二級緩存的物理介質(zhì)可以使內(nèi)存和硬盤,因此第二級緩存可以存放大容量的數(shù)據(jù),數(shù)據(jù)過期策略的maxElementsInMemory屬性可以控制內(nèi)存中的對象數(shù)目,管理二級緩存主要包括兩個方面:選擇需要使用第二級緩存的持久化類,設(shè)置合適的并發(fā)訪問策略;選擇緩存適配器,設(shè)置合適的數(shù)據(jù)過期策略。SessionFactory的evit()方法也可以顯示的清空緩存中特定對象,但不推薦 |
到此,相信大家對“Hibernate緩存機(jī)制的原理”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。