Hibernate學習(三):Session的緩存及對象的狀態

對於session這個接口的學習能夠說是最痛苦也是最複雜的,由於它所涉及的方面太多了,一些隱藏的機制也不少,誰讓它是Central API呢。對於它的幾個最基本的方法如save()、delete()、flush()等的學習都花了我必定的時間。在深刻了解這些這些方法前,瞭解session的緩存機制以及Hibernate中Java對象的狀態對咱們是頗有幫助的。數據庫

一.Session的緩存緩存

       Java是純面向對象的語言,所以不可能像C語言那樣直接操縱內存,例如聲明一段可用的內存空間。在Java裏面,緩存一般是指Java對象的屬性佔用的內存空間,一般是一些集合類型的屬性。在session接口的實現類SessionImpl中定義了一系列的Java集合,這些Java集合就構成了Session的緩存。
       使用緩存的一個很明顯的好處就是能夠減小數據庫訪問的頻率,提升應用程序的性能,由於從內存中讀取數據顯然要比從數據庫中查詢快多了。根據我我的的理解,Session的緩存實際上起到了一個「過渡倉庫」做用。就像魔獸中的英雄同樣,身上都會背有一個包,用來存放經常使用的物品如補血藥水、補魔藥水、回城卷等等。若是想用回城卷而身上沒有回程卷的話就要跑到商店去shopping了,這樣就會浪費大量的時間了,除非你此刻就在商店旁邊;若是想用的回城卷的時候身上就有的話,英雄就能夠直接用而沒必要大老遠的跑到商店去了。咱們的Session的緩存能夠說就至關於英雄身上的揹包,個人應用程序就是英雄,而數據庫就是商店咯,以下圖所示。固然這個比喻不是很準確了,比方說在Hibernate應用中咱們能夠向數據庫插入一條新的記錄,而在魔獸中你是不可能給商店增長存貨量的,只是爲了便於理解,才做了這麼一個對比。session

二.Hibernate中Java對象的狀態ide

在一個Hibernate應用中,Java對象能夠處於如下三個狀態之一:性能

1.臨時狀態(Transient)。處於這個狀態的對象還被沒有歸入Hibernate的緩存管理體系,跟任何session都不關聯,在數據庫中也沒有對應的記錄。
2.持久化狀態(Persistent)。處於這個狀態的對象位於Session的緩存中,而且和數據庫中的一條數據記錄相對應。
3.遊離狀態(Detached)。處於這個狀態的對象再也不位於Session的緩存中,它與臨時對象的最大區別在於,遊離對象在數據庫中還可能存在一條與它對應的記錄學習

          上述3個狀態之間是能夠相互轉化的,並且咱們所說的狀態都是針對某一個session實例而言的,比方說,對象A對於session1而言是處於持久化狀態的,由於它處於session1的緩存中,可是對於session2而言對象A並不在它的緩存中,所以它是處於遊離狀態的。
          對於這幾個狀態的理解花費了我必定的時間,由於老是有一些稀奇古怪的念頭在我腦海中產生。好比說,對於臨時狀態的定義,若是我新建一個對象,而後人爲的讓它屬性的值和數據庫中的一條記錄對應,包括id的取值都同樣。此時它可否說是處於遊離狀態呢?由於它和一條記錄想對應呀。實際上這些狀況都是因爲一些不和規範的操做而產生的。在Hibernate應用中,不管Java對象處於臨時狀態、持久化狀態仍是遊離狀態,應用程序都不該該修改它的OID。OID的值應該由Hibernate來維護和負責,實際上Hibernate在同步緩存中的對象與數據庫中的記錄時,都是經過OID來進行關聯和映射的,若是應用程序人爲的修改了對象的OID,就會致使一些莫名其妙的錯誤,並且這樣也不利於數據的同步。
             至於對象之間的狀態轉化,若是跟session的各個方法放在一塊兒討論的話可能會更容易理解,這裏就不贅述了。spa

相關文章
相關標籤/搜索