NHibernate原始碼三 續 資料持久化

2021-09-05 15:49:15 字數 2711 閱讀 4876

// materialize associations (and initialize the object) later

hydratedobjects.add(obj);

for (int i=0; iif ( persister.ismutable && (cannotdirtycheck ||

(dirtyproperties!=null && dirtyproperties.length!=0 ) ||

(status==status.loaded && persister.isversioned &&

persister.hascollections &&

searchfordirtycollections(values, types) ) ) )

substitute = substitute || intercepted;

if(status == status.loaded && persister.implementsvalidatable)

object updatedstate = null;

if(status==status.loaded)

updates.add(

new scheduledupdate(entry.id, values, dirtyproperties, entry.version,

nextversion, obj, updatedstate, persister, this)

);} }}

}首先取得屬性的值,這個通過物件的持久化類的getpropertyvalues方法來獲得,這個方法與前面設定物件屬性的setpropertyvalues是相反的;

然後查詢已更改的屬性,nh把控制權交給了interceptor(***),在finddirty中,我們可以設定已發生更改的屬性,這看起來是個不錯的處理,例如:在字段級許可權中,可以根據許可權限制某些屬性不被更改。如果不進行處理,一定要記得返回乙個null值哦,這時由物件的持久化類來查詢已更改的屬性(finddirty方法),如果檢查出物件是髒的(dirty), 就進行後續處理。

接下來nh再次將控制權交給了interceptor, 這次呼叫的是onflushdirty, 這樣我們又得到了乙個處理物件的機會,至於能做些什麼,那就要看大家的想像力了,最簡單的就是記錄更新日誌log。:-)

注意這個方法有個返回值,預設是返回false, 如果你修改了values的內容,並且需要更新,那麼應返回true, 這將再次呼叫物件持久化類的finddirty方法,前提是你沒有自行處理interceptor的finddirty方法。

再接下來,檢查物件是否實現了ivalidatable(驗證)介面, 如有實現則呼叫ivalidatable.validate方法。強烈建議所有的持久物件都應實現ivalidable, 雖然可以在對映檔案中指定一些約束,但這些約束的處理顯然比在ivalidatable介面中處理要晚,乙個比較關健的是可以提供一致的資料校驗介面(如驗證失敗,丟擲乙個validateexception, 並附上驗證失敗的錯誤資訊),這樣在表示層或業務層只要乙個簡單的處理就可以了。

最後將物件加入更新集合中,等待下一步處理。

// *** session.cs 2392行 ***

private void execute()

catch (exception e)

}處理所有存放在任務集合中的物件。

// *** session.cs 2450行 ***

private void executeall(icollection coll)

if ( batcher!=null ) batcher.executebatch();

}遍歷coll, 然後呼叫iexecutable.execute方法進行真正的持久化操作。

// *** scheduledupdate.cs 33行 ***

public override void execute()

通過物件的持久化類進行更新操作。

// *** entitypersister.cs 998行 ***

protected virtual void update(object id, object fields, bool includeproperty,

object oldversion, object obj, sqlstring sqlupdatestring, isessionimplementor session)

catch (exception e)

}上面的**看起來有點怪,不過顯然是batcher(批處理器)尚未完成的**。

dehydrate用於把與字段對應的屬性值賦值到statement的引數中。

// *** session 2438行 ***

public void postupdate(object obj, object updatedstate, object nextversion)

}調整session實體集合中物件的狀態。

// *** session.cs 2852行 ***

private void postflush()

interceptor.postflush( entitiesbykey.values );

}呼叫***的postflush方法,傳遞會話中的所有實體。

資料更新的持久化操作到此就結束了,與我們設想的一點出入,就是最後並沒把最新的屬性值存入到實體集合中,只是更改了loadedstate和lockmode,

至於為什麼,就能給大家去思考一些吧?

NHibernate原始碼分析之三 續 資料持久化

當持久化物件時,顯然必須存在把記錄的值賦值到物件屬性和取得物件屬性的值用於持久化操作,對於更新操作,還需要檢查物件的值是否已發生變化,即是否為dirty,這些操作都是由物件的持久化類來完成的。有關持久化類可參考 會話和持久化操作 一文。下面對nh的原始碼進行分析,以了解nh中資料載入和更新的過程。一...

nhibernate原始碼七 HQL資料載入

nh中,hql是乙個十分強大的物件導向的查詢語言,簡單的說,就是不需要使用實際的表名和列名來查詢資料,而改用類名和屬性。有兩種方式來執行hql資料載入,一種是直接使用isession的find方法,另一種是使用iquery介面。iquery介面提供了一些額外的設定,最重要的就是分頁了,這個和icri...

WebScarab關鍵原始碼分析(3)(續)

接上篇。接下來是兩個if,如果接收到的是401或者407返回碼 其含義分別為需驗證和 伺服器需驗證 則重新調整驗證資訊,並在下乙個while裡繼續請求內容。再乙個是判斷如果request使用的是head方法,則setnobody 因為head方法是不可能有內容部分的,呼叫setnobody後未讀取的...