【引用】http://davidwei05951983.spaces.live.com/Blog/cns!BED3D557991594B3!812.entry
session的常用基本操作有:
Transient instances may be made persistent by calling save(),persist() or saveOrUpdate(). Persistent instances may be made transient by calling delete(). Any instance returned by a get() or load() method is persistent. Detached instances may be made persistent by calling update(), saveOrUpdate(), lock() or replicate(). The state of a transient or detached instance may also be made persistent as a new persistent instance by calling merge().save() and persist() result in an SQL INSERT, delete() in an SQL DELETE and update() or merge() in an SQL UPDATE. Changes to persistent instances are detected at flush time and also result in an SQL UPDATE. saveOrUpdate() and replicate() result in either an INSERT or an UPDATE.
persist():
Make a transient instance persistent. This operation cascades to associated instances if the association is mapped with cascade="persist". The semantics of this method are defined by JSR-220.
當(dāng)級聯(lián)風(fēng)格為persist時,這個操作會級聯(lián)操作關(guān)聯(lián)的對象。這個方法的語義是JSR-220定義的。
persist() is well defined. It makes a transient instance persistent. However,
it doesn't guarantee that the identifier value will be assigned to the persistent
instance immediately, the assignment might happen at flush time. The spec doesn't say
that, which is the problem I have with persist().
persist() also guarantees that it will not execute an INSERT statement if it is
called outside of transaction boundaries. This is useful in long-running conversations
with an extended Session/persistence context.A method like persist() is required.
save() does not guarantee the same, it returns an identifier, and if an INSERT
has to be executed to get the identifier (e.g. "identity" generator, not "sequence"),
this INSERT happens immediately, no matter if you are inside or outside of a transaction. This is not good in a long-running conversation with an extended Session/persistence context."
save():
Persist the given transient instance, first assigning a generated identifier. (Or using the current value of the identifier property if the assigned generator is used.) This operation cascades to associated instances if the association is mapped with cascade="save-update".
首先會賦予一個標(biāo)志符,然后持久化給定的對象。但是如果使用assigned 標(biāo)志符產(chǎn)生方法,則會使用當(dāng)前的標(biāo)志符值。如果級聯(lián)風(fēng)格為save-pdate,則會持久化相應(yīng)的關(guān)聯(lián)對象.
merge():
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge". The semantics of this method are defined by JSR-220.
拷貝當(dāng)前的對象的狀態(tài)到相同標(biāo)志符的持久化對象的狀態(tài)。如果當(dāng)前關(guān)聯(lián)的session中沒有持久化對象,Hibernate會加載該對象,并返回這個持久化對象。如果給定的對象沒有保存,則Hibernate保存該副本,返回這個新持久化的對象,但給定的對象并沒有和session關(guān)聯(lián)。如果指定級聯(lián)風(fēng)格為merge,則會級聯(lián)關(guān)聯(lián)對象。該方法的語義是JSR-200定義的。
saveOrUpdate():
Either {@link #save(String, Object)} or {@link #update(String, Object)} the given instance, depending upon resolution of the unsaved-value checks (see the manual for discussion of unsaved-value checking). This operation cascades to associated instances if the association is mapped with cascade="save-update".
保存或更新給定對象,取決于給定對象的持久化狀態(tài)。默認(rèn)情況下是保存,在指定標(biāo)志符元素屬性為unsaved-value時則會調(diào)整。如果級聯(lián)風(fēng)格為"save-update",則會級聯(lián)相關(guān)聯(lián)的對象
delete():
Remove a persistent instance from the datastore. The object argument may be an instance associated with the receiving Session or a transient instance with an identifier associated with existing persistent state. This operation cascades to associated instances if the association is mapped with cascade="delete".
刪除對象。
lock():
Obtain the specified lock level upon the given object. This may be used to perform a version check (LockMode.READ), to upgrade to a pessimistic lock (LockMode.UPGRADE), or to simply reassociate a transient instance with a session (LockMode.NONE). This operation cascades to associated instances if the association is mapped with cascade="lock".
用于對指定對象設(shè)置參數(shù)中給定的鎖。如果鎖為LockMode.READ,可以用來執(zhí)行版本檢查;如果鎖為LockMode.UPGRADE則用來執(zhí)行悲觀鎖。如果定為LockMode.NONE,則僅僅時持久化一個未持久化的對象。如果級聯(lián)風(fēng)格為lock,會級聯(lián)相關(guān)聯(lián)的對象。
refresh():
Re-read the state of the given instance from the underlying database. It is inadvisable to use this to implement long-running sessions that span many business tasks. This method is, however, useful in certain special circumstances.For example where a database trigger alters the object state upon insert or update after executing direct SQL (eg. a mass update) in the same session after inserting a Blob or Clob.
從當(dāng)前數(shù)據(jù)庫中重新讀取給定對象的狀態(tài)。這在執(zhí)行跨越多個業(yè)務(wù)任務(wù)的長時間session中優(yōu)勢不顯著,在少數(shù)特定環(huán)境下還是有用的,例如: 插入或更新后數(shù)據(jù)庫觸發(fā)器更改了對象的狀態(tài)。當(dāng)前session中執(zhí)行完原生SQL后(如批量更新)。 插入Blob或Clob對象后。
evict():
Remove this instance from the session cache. Changes to the instance will not be synchronized with the database. This operation cascades to associated instances if the association is mapped with cascade="evict".
從session的緩存中去除當(dāng)前實例。執(zhí)行后對象的改變將不再和數(shù)據(jù)庫保持同步。當(dāng)指定級聯(lián)風(fēng)格為'evict’時,會級聯(lián)操作關(guān)聯(lián)對象。我用的時候主要是用于批量操作的時候,清空緩存,防止內(nèi)存緊張。
replicate():
Persist the state of the given detached instance, reusing the current identifier value. This operation cascades to associated instances if the association is mapped with cascade="replicate"
重用當(dāng)前的標(biāo)志符,持久化當(dāng)前已經(jīng)脫離session的對象的狀態(tài)。具體的操作和要看參數(shù)ReplicationMode。如果是ReplicationMode.EXCEPTION,則在復(fù)制時如果有重復(fù)的行數(shù)據(jù),則拋出異常。ReplicationMode.IGNORE則忽略異常。ReplicationMode.OVERWRITE則會覆蓋掉已有行數(shù)據(jù)。ReplicationMode.LATEST_VERSION則是在有重復(fù)時使用最新的版本進(jìn)行控制。
自動狀態(tài)檢測
Hibernate的用戶曾要求一個既可自動分配新持久化標(biāo)識(identifier)保存瞬時(transient)對象,又可更新/重新關(guān)聯(lián)脫管(detached)實例的通用方法。 saveOrUpdate()方法實現(xiàn)了這個功能。 saveOrUpdate()用途和語義可能會使新用戶感到迷惑。 首先,只要你沒有嘗試在某個session中使用來自另一session的實例,你就應(yīng)該不需要使用update(), saveOrUpdate(),或merge()。有些程序從來不用些方法。
通常下面的場景會使用update()或saveOrUpdate():
程序在第一個session中加載對象
該對象被傳遞到表現(xiàn)層
對象發(fā)生了一些改動
該對象被返回到業(yè)務(wù)邏輯層
程序調(diào)用第二個session的update()方法持久這些改動
saveOrUpdate()做下面的事:
如果對象已經(jīng)在本session中持久化了,不做任何事
如果另一個與本session關(guān)聯(lián)的對象擁有相同的持久化標(biāo)識(identifier),拋出一個異常
如果對象沒有持久化標(biāo)識(identifier)屬性,對其調(diào)用save()
如果對象的持久標(biāo)識(identifier)表明其是一個新實例化的對象,對其調(diào)用save()
如果對象是附帶版本信息的(通過<version>或<timestamp>) 并且版本屬性的值表明其是一個新實例化的對象,save()它。
否則update() 這個對象
merge()可非常不同:
如果session中存在相同持久化標(biāo)識(identifier)的實例,用用戶給出的對象的狀態(tài)覆蓋舊有的持久實例
如果session沒有相應(yīng)的持久實例,則嘗試從數(shù)據(jù)庫中加載,或創(chuàng)建新的持久化實例 ,最后返回該持久實例
用戶給出的這個對象沒有被關(guān)聯(lián)到session上,它依舊是脫管的.
Session刷出(flush)
每間隔一段時間,Session會執(zhí)行一些必需的SQL語句來把內(nèi)存中的對象的狀態(tài)同步到JDBC連接中。這個過程被稱為刷出(flush),默認(rèn)會在下面的時間點執(zhí)行:
a.在某些查詢執(zhí)行之前
b.在調(diào)用org.hibernate.Transaction.commit()的時候
c.在調(diào)用Session.flush()的時候
涉及的SQL語句會按照下面的順序發(fā)出執(zhí)行:
所有對實體進(jìn)行插入的語句,其順序按照對象執(zhí)行Session.save()的時間順序
所有對實體進(jìn)行更新的語句
所有進(jìn)行集合刪除的語句
所有對集合元素進(jìn)行刪除,更新或者插入的語句
所有進(jìn)行集合插入的語句
所有對實體進(jìn)行刪除的語句,其順序按照對象執(zhí)行Session.delete()的時間順序
(有一個例外是,如果對象使用native方式來生成ID(持久化標(biāo)識)的話,它們一執(zhí)行save就會被插入。)
除非你明確地發(fā)出了flush()指令,關(guān)于Session何時會執(zhí)行這些JDBC調(diào)用是完全無法保證的,只能保證它們執(zhí)行的前后順序。 當(dāng)然,Hibernate保證,Query.list(..)絕對不會返回已經(jīng)失效的數(shù)據(jù),也不會返回錯誤數(shù)據(jù)。
也可以改變默認(rèn)的設(shè)置,來讓刷出(flush)操作發(fā)生的不那么頻繁。 FlushMode類定義了三種不同的方式。 僅在提交時刷出(僅當(dāng)Hibernate的Transaction API被使用時有效), 按照剛才說的方式刷出, 以及除非明確使用flush()否則從不刷出。 最后一種模式對于那些需要長時間保持Session為打開或者斷線狀態(tài)的長時間運行的工作單元很有用。
父子關(guān)系的級聯(lián)(cascading)操作準(zhǔn)確語義如下:
如果父對象被persist(),那么所有子對象也會被persist()
如果父對象被merge(),那么所有子對象也會被merge()
如果父對象被save(),update()或 saveOrUpdate(),那么所有子對象則會被saveOrUpdate()
如果某個持久的父對象引用了瞬時(transient)或者脫管(detached)的子對象,那么子對象將會被saveOrUpdate()
如果父對象被刪除,那么所有子對象也會被delete()
除非被標(biāo)記為cascade="delete-orphan"(刪除“孤兒”模式,此時不被任何一個父對象引用的子對象會被刪除), 否則子對象失掉父對象對其的引用時,什么事也不會發(fā)生。 如果有特殊需要,應(yīng)用程序可通過顯式調(diào)用delete()刪除子對象。