1. 程式人生 > >JavaEE--SSH--hibernate-物件識別符號,一級快取,快照機制

JavaEE--SSH--hibernate-物件識別符號,一級快取,快照機制

hibernate 物件識別符號(OID),物件狀態,一級快取以及快照機制:

一.首先介紹一下OID(物件識別符號)

什麼是OID:

OID是關係資料庫中主鍵在Java物件模型中的等價物.Hibernate根據OID來維持Java物件和資料庫中的對應關係。OID可以確保物件的唯一性.

也就是說hibernate內部有一個屬性專門區分不同物件的主鍵屬性值是否相同.如果相同則代表這個物件不是唯一的,就會報錯.

程式碼測試:

public void test03(){
//測試Hibernate如何區分不同的物件
//將LinkMan.hbm.xml中id標籤內的generator手動設定
//<generator class="assigned"></generator>
//修改Hibernate.cfg.xml中的配置
//<property name="hibernate.hbm2ddl.auto">create</property>
LinkMan m1=new LinkMan();
LinkMan m2=new LinkMan();
m1.setLkmId(new Long(1));
m2.setLkmId(new Long(2));//如果ID值都是1,報錯
// A different object with the same identifier value was already associated with the session :
m1.setLkmName("tom");
m2.setLkmName("tom");
Session sess = HibernateUtil.getOpenSession();
Transaction tx = sess.beginTransaction();
sess.save(m1);
sess.save(m2);
tx.commit();
sess.close();

}

二.物件的狀態:

hibernate為了方便管理持久化物件,將物件分為三種狀態.

瞬時態,持久態和脫管態(遊離態)

瞬時態:剛建立好的Java物件,其上沒有生成物件識別符號(OID),也沒有納入session管理.資料庫中沒有與之對應的資料.

持久態:有物件識別符號.納入session管理資料庫中可能有與之對應的資料,也可能沒有.

脫管態:有物件識別符號,session已經失去了對它的管理.

三種狀態如何轉換:

瞬時態->持久態 save update

瞬時態->託管態 setId() //設定物件識別符號(OID),而且必須是資料庫中存在的

持久態->瞬時態 delete

持久態->脫管態 close

脫管態->瞬時態 將id設定為null 

脫管態->持久態 update,save


三.那什麼是一級快取呢:

先說說快取:快取就是把系統中經常訪問的資料,從資料庫中獲取到放到快取中.減少與資料庫的訪問次數,優點是減輕了資料庫的壓力,提高了效能.

而hibernate也提供了這樣的快取,分為一級快取,二級快取(不常用不說了).

一級快取是session級別的快取.只要session存在,session的資料也會存在.而所有的持久態物件都會儲存在一級快取當中.

一級快取的存在感:

當我們第一次從資料庫中get/load時,會發送SQL從資料庫進行查詢.

          第二次get/load時(同一OID物件),會直接從快取中讀取資料.不會發送SQL.

一級快取的特點:

1.當呼叫session的save(),update(),saveOrUpdate()時,如果session快取中沒有相應物件,會自動查詢並放入一級快取中.

2.當呼叫session的load()/get(),以及query的list(),iterator()時,如果如果session快取中沒有相應物件,會自動查詢並放入一級快取中.

3.當呼叫session的close方法後,session的快取會被清空.

這裡順便提一下get()和load()的區別

1.發出sql語句時機不同:

get()是立即發出sql

load()是延遲載入.只有用到載入的資料時才傳送sql

2.返回的結果不一樣.

get() 返回實際的物件

load() 返回代理物件

四.一級快取下的快照機制:

快照其實是資料在記憶體中的副本,是資料庫的資料在記憶體中的對映.

快照的作用是跟資料庫資料保持一致,

原理:

當我們第一次查詢的時候,查到的資料會儲存兩份,一份給一級快取,一份給快照.

當我們對資料進行修改後(實際是修改一級快取中的實體類物件),執行flush()或commit()時,hibernate會比較一級快取的資料和快照的資料是否相同,如果不同,會將一級快取的資料用sql形式發到資料庫,並且同步快照.

快照的作用:

利用快照技術進行更新,不需要手動呼叫update方法,當我們commit()/flush()時會自動發出update語句.來確保資料庫-一級快取-快照三者資料的一致性.