首先要知道的是:
Hibernate會(huì)盡量將與數(shù)據(jù)庫(kù)的操作延遲,直到必須要與數(shù)據(jù)庫(kù)進(jìn)行交互,例如save方法一般會(huì)在提交時(shí)才真正執(zhí)行,最終在提交時(shí)會(huì)以批處理的方式與數(shù)據(jù)庫(kù)進(jìn)行交互,以提高效率。
而將操作延遲,就是利用緩存,將最后要處理的操作放到緩存中。
flush方法的主要作用就是清理緩存,強(qiáng)制數(shù)據(jù)庫(kù)與Hibernate緩存同步,以保證數(shù)據(jù)的一致性。它的主要?jiǎng)幼骶褪窍驍?shù)據(jù)庫(kù)發(fā)送一系列的sql語(yǔ)句,并執(zhí)行這些sql語(yǔ)句,但是不會(huì)向數(shù)據(jù)庫(kù)提交。而commit方法則會(huì)首先調(diào)用flush方法,然后提交事務(wù)。
在下面的情況下,Hibernate會(huì)調(diào)用Session.flush()以清理緩存:
1)事務(wù)提交時(shí),如果flush模式不為FlushMode.NEVER,commit()將調(diào)用flush().
2)在某些查詢(xún)語(yǔ)句之前(此查詢(xún)語(yǔ)句之前的語(yǔ)句已經(jīng)改變了數(shù)據(jù)庫(kù)狀態(tài),所以需要調(diào)用flush()以同步數(shù)據(jù)庫(kù)是查出來(lái)的數(shù)據(jù)是經(jīng)過(guò)更改的)。
除非明確地指定了flush()命令,否則關(guān)于Session何時(shí)會(huì)執(zhí)行這些JDBC調(diào)用完全是無(wú)法保證的,只能保證他們執(zhí)行的前后順序。
通過(guò)設(shè)置session.setFlushMode(),可以精確控制Hibernate的FlushMode.
(1) FlushMode.AUTO:Hibernate判斷對(duì)象屬性有沒(méi)有改變,如果被更改成為臟數(shù)據(jù),則在一個(gè)查詢(xún)語(yǔ)句前將更新此改動(dòng)以保證數(shù)據(jù)庫(kù)的同步。這也是Hibernate的默認(rèn)清理模式。
(2) FlushMode.COMMIT:在事務(wù)結(jié)束之前清理session的緩存。這樣有可能導(dǎo)致查出臟數(shù)據(jù)
(3) FlushMode.NEVER:除非強(qiáng)制調(diào)用Session.flush(),否則永遠(yuǎn)不清理Session。相當(dāng)于將數(shù)據(jù)庫(kù)設(shè)置為一個(gè)只讀的數(shù)據(jù)庫(kù)。
【如果此時(shí)進(jìn)行數(shù)據(jù)的寫(xiě)入操作,會(huì)發(fā)生錯(cuò)誤】
(4) FlushMode.ALWAYS:在每一個(gè)查詢(xún)數(shù)據(jù)之前都調(diào)用Session.flush()。很顯然這種效率很低。
在調(diào)用Session.flush()時(shí),涉及的SQL語(yǔ)句會(huì)按照下面的順序執(zhí)行。
(1) 所有的實(shí)體進(jìn)行插入的語(yǔ)句,其順序按照對(duì)象執(zhí)行Session.save()的時(shí)間順序。
(2) 所有對(duì)實(shí)體進(jìn)行更新的語(yǔ)句
(3) 所有對(duì)集合元素進(jìn)行刪除,更新或者插入的語(yǔ)句
(4) 所有對(duì)實(shí)體經(jīng)行刪除的語(yǔ)句,其順序按照對(duì)象執(zhí)行Session.delete()的時(shí)間順序。
(5) 有一個(gè)例外是,如果對(duì)象使用native方式生成的ID(持久化標(biāo)識(shí)),則他們一執(zhí)行save就會(huì)被插入。
【因?yàn)閚ative方式若想得到主鍵,必須與數(shù)據(jù)庫(kù)交互,而hilo方式則不用】)
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/MageShuai/archive/2009/09/11/4544202.aspx