是什麼?
站在持久化的角度, Hibernate 把對象分爲 4 種狀態: 持久化狀態, 臨時狀態, 遊離狀態, 刪除狀態. Session 的特定方法能使對象從一個狀態轉換到另一個狀態.
臨時對象:1.在使用代理主鍵的情況下,OID通常爲null, 2. session緩存中沒有該對象 3. 在數據庫中沒有相對應的記錄。
持久化對象 :1.OID不爲null 2.位於Session緩存中 3.在數據庫中有和與之相對應的記錄 4.Session在flush緩存的時候,會根據持久化對象的屬相變化,來同步更新數據庫
刪除對象: 1.數據庫中沒有與之相對應的記錄,2. 不在Session緩存中
遊離對象: 1.OID不爲null 2.session沒有該對象 3.在數據庫中存在與之對應的記錄
四種狀態之間如何轉換?
save()和persist()方法的區別
save() 方法: 1).執行 INSERT 操作, 使一個臨時對象變爲持久化對象 2). 爲對象分配 ID. 3). 在 flush 緩存時會發送一條 INSERT 語句. 4). 在 save 方法之前的 id 是無效的 5). 持久化對象的 ID 是不能被修改的!
persist(): 也會執行 INSERT 操作,但是在調用 persist 方法之前, 若對象已經有 OID 了, 則不會執行 INSERT, 而拋出異常
get()和load()方法的區別
1.get()立即檢索,load()延遲檢索,只有在使用該對象的時候纔會加載
2.如果Session在關閉之後,調用load()方法,則會拋出LazyInitializationException 異常,get()則不會拋出異常
3.若數據表中沒有對應的記錄, Session 也沒有被關閉,調用load()方法,如果不使用該對象,就沒有問題,一旦使用該對象,會去加載,這個時候就會拋出異常。get()方 法返回null
update()方法
1. 若更新一個持久化對象, 不需要顯示的調用 update 方法. 因爲在調用 Transaction的 commit() 方法時, 會先執行 session 的 flush 方法.
2. 更新一個遊離對象, 需要顯式的調用 session 的 update 方法. 可以把一個遊離對象變爲持久化對象.
需要注意的是:
1). 無論要更新的遊離對象和數據表的記錄是否一致, 都會發送 UPDATE 語句.如何能讓 updat 方法不再盲目的出發 update 語句呢 ?在 .hbm.xml 文件的 class 節點設置select-before-update=true (默認爲 false). 但通常不需要設置該屬性.
2).若數據表中沒有對應的記錄, 但還調用了 update 方法, 會拋出異常
3).當 update() 方法關聯一個遊離對象時,如果在 Session 的緩存中已經存在相同 OID 的持久化對象, 會拋出異常. 因爲在 Session 緩存中不能有兩個 OID 相同的對象!
saveOrUpdate()方法
1.若該對象爲臨時狀態(OID爲null),則save,若爲遊離態(OID不爲null)則update
2.需要注意:當OID不爲null,即爲遊離態,但修改了OID,在數據表中不能找到與之想對應的數據記錄,這個時候就會拋出一個異常。
Delete()方法
1.delete: 執行刪除操作. 只要 OID 和數據表中一條記錄對應, 就會準備執行 delete 操作,反之拋出異常。
2.需要注意:執行完delete方法之後,對象的OID還依然存在,怎麼解決呢?
需要在hibernate.cfg.cml文件中設置 <property name="use_identifier_rollback">true</property>
evict()方法
從session中把指定的持久化對象移除
在Hibernate中調用存儲過程
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
connection.prepareStatement("sql");
}
});