天天看點

NHibernate之映射檔案配置說明(轉載1)二. class三、 id四、(主鍵生成政策)generator五、composite-id 聯合ID

  這個元素包括以下可選的屬性。schema屬性,指明了這個映射所引用的表所在的schema名稱。假若指定了這個屬性,

表名會加上所指定的schema的名字擴充為全限定名。假若沒有指定,表名就不會使用全限定名。default-cascade 指定了未明确注明cascade屬性的.Net屬性和集合類.Net會采取什麼樣的預設級聯風格。 auto-import屬性預設讓我們在查詢語言中可以使用非全限定名的類名。assembly和namespace指定了持久化類的應用程式集名稱和其所在的名稱空間名。

 各選項說明:

(1)

schema (optional): 資料庫schema名稱。

(2)

default-cascade (可選 - 預設為 none):

預設的級聯風格。

(3)

auto-import (optional - defaults

to true): 指定我們在使用查詢語句的時候是否可以使用非全限定名。

(4)(5)

assembly and namespace(可選):

指定映射檔案中的類的應用程式集名稱和其所在的名稱空間名,用來生成類的非全限定名。

  如果沒有設定assembly何namespace标簽,我們不得不使用類的非全限定名 (namespace.類名,assembly).

  假若你有兩個持久化類,它們的非全限定名是一樣的,你應該設定auto-import="false"。

假若說你把一個“import過”的名字同時對應兩個類, NHibernate會抛出一個異常。

 你可以使用class元素來定義一個持久化類:

各選項說明:

name: 持久化類(或者接口)的.NET全限定名。

table: 對應的資料庫表名。

discriminator-value(辨識值) (可選 -

預設和類名一樣):一個用于區分不同的子類的值,在多态行為時使用。可選值包括null和not null。

(4)

mutable (可選, 預設值為 true):

表明該類的執行個體可變(不可變)。

(5)

schema (可選) 覆寫在根元素中指定的schema名字。

(6)

proxy (可選)指定一個接口,在延遲裝載時作為代理使用。你可以在這裡使用該類自己的名字。

(7)

dynamic-update (可選,預設為false): 指定用于UPDATE 的SQL将會在運作時動态生成,并且隻更新那些改變過的字段。

(8)

dynamic-insert (可選, 預設為false):

指定用于 INSERT的 SQL

将會在運作時動态生成,并且隻包含那些非空值字段。

(9)

select-before-update (可選,預設值為 false):

指定NHibernate除非确定對象的确被修改了,UPDATE操作。在特定場合(實際上,隻會發生在一個臨時對象關聯到一個新的session中去,執行update()的時候),這說明NHibernate會在UPDATE之前執行一次額外的SQLSELECT操作,來決定是否應該進行UPDATE。

(10)

polymorphism (可選, 預設值為 implicit (隐式)):

界定是隐式還是顯式的使用查詢多态。

(11)

where (可選) 指定一個附加的SQL WHERE 條件,在抓取這個類的對象時會一直增加這個條件。

(12)

persister (可選): 指定一個定制的 IClassPersister。

(13)

batch-size (可選,預設是1)

指定一個用于根據辨別符抓取執行個體時使用的"batch size"(批次抓取數量)。

(14)

optimistic-lock (樂觀鎖定) (可選,預設是version):

決定樂觀鎖定的政策。

(15)

lazy (可選): 假若設定lazy="false",就會禁用延遲加載。

(16)

abstract(可選) 用于在<union-subclass>的繼承結構 (hierarchies)中辨別抽象超類。

 若指明的持久化類實際上是一個接口,這也是完全可以接受的。 之後你可以用元素 <subclass>來指定該接口的實際實作類。 你可以持久化任何static(靜态的)内部類。

你應該使用标準的類名格式來指定類名,比如:Eg.Foo+Bar,

Eg。由于HQL解析器的限制NHibernate 1.0 無法在查詢裡使用内部類。

  不可變類 mutable="false"不可以被應用程式更新或者删除。

這可以讓NHibernate做一些小小的性能優化。

  可選的proxy屬性允許延遲加載類的持久化執行個體。

NHibernate開始會傳回實作了這個命名接口的代理類。當代理的某個方法被實際調用的時候,

真實的持久化對象才會被裝載。參見下面的“用于延遲裝載的代理”。

  Implicit (隐式)的多态是指,如果查詢時給出的是任何超類、該類實作的接口或者該類的

名字,都會傳回這個類的執行個體;如果查詢中給出的是子類的名字,則會傳回子類的執行個體。 Explicit (顯式)的多态是指,隻有在查詢時給出明确的該類名字時才會傳回這個類的執行個體;

同時隻有在這個<class>的定義中作為<subclass>或者<joined-subclass>出現的子類,才會可能傳回。 在大多數情況下,預設的polymorphism="implicit"都是合适的。

顯式的多态在有兩個不同的類映射到同一個表的時候很有用。(允許一個“輕型”的類,隻包含部分表字段)。

  persister屬性可以讓你定制這個類使用的持久化政策。 你可以指定你自己實作NHibernate.Persister.EntityPersister的子類,你甚至可以完全從頭開始編寫一個NHibernate.Persister.IClassPersister接口的實作,

比如是用儲存過程調用、序列化到檔案或者LDAP資料庫來實作。 參閱NHibernate.DomainModel.CustomPersister,這是一個簡單的例子 (“持久化”Hashtable)。

  請注意dynamic-updatee和dynamic-insert的設定并不會繼承到子類, 是以在<subclass>或者<joined-subclass>元素中可能

需要再次設定。這些設定是否能夠提高效率要視情形而定。請用你的智慧決定是否使用。

  使用select-before-update通常會降低性能。如果你重新連接配接一個脫管(detache)對象執行個體

到一個Session中時,它可以防止資料庫不必要的觸發update。 這就很有用了。

如果你打開了dynamic-update,你可以選擇幾種樂觀鎖定的政策:

version(版本檢查) 檢查version/timestamp字段

all(全部) 檢查全部字段

dirty(髒檢查)隻檢察修改過的字段

none(不檢查)不使用樂觀鎖定

  我們非常強烈建議你在NHibernate中使用version/timestamp字段來進行樂觀鎖定。

對性能來說,這是最好的選擇,并且這也是唯一能夠處理在session外進行操作的政策(例如: 在使用ISession.Update()的時候)。注意version或者是timestamp屬性不能為null,不管是否使用了unsaved-value政策,或者是執行個體被作為是瞬态。

  從NHibernate 1.2.0開始,版本号從1開始(以前的版本從0開始),這樣允許把version的屬性的unsaved-value設定為0。

 被映射的類必須定義對應資料庫表主鍵字段。大多數類有一個屬性, 為每一個執行個體包含唯一的辨別。

元素定義了該屬性到資料庫表主鍵字段的映射。

name (可選): 辨別屬性的名字。

type(可選): 辨別NHibernate類型的名字。

column(可選 - 預設為屬性名): 主鍵字段的名字。

unsaved-value (可選 -

預設為一個切合實際(sensible)的值): 一個特定的辨別屬性值,用來标志該執行個體是剛剛建立的,尚未儲存。

這可以把這種執行個體和從以前的session中裝載過(可能又做過修改--譯者注) 但未再次持久化的執行個體區分開來。

access (可選 - 預設為property):

NHibernate用來通路屬性值的政策。

  如果name屬性不存在,會認為這個類沒有辨別屬性。

  可選的<generator>子元素是一個.NET類的名字,

用來為該持久化類的執行個體生成唯一的辨別。如果這個生成器執行個體需要某些配置值或者初始化參數, 用元素來傳遞。

 所有的生成器都實作NHibernate.Id.IIdentifierGenerator接口。 這是一個非常簡單的接口;

某些應用程式可以選擇提供他們自己特定的實作。當然, NHibernate提供了很多内置的實作。下面是一些内置生成器的快捷名字:

<dl></dl>

<dt>  1、increment</dt>

<dd></dd>

用于為int類型生成 唯一辨別。隻有在沒有其他程序往同一張表中插入資料時才能使用。 在叢集下不要使用。

<dt>  2、identity</dt>

對DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置辨別字段提供支援。資料庫傳回的主鍵值

傳回的辨別符是int類型的。

<dt>  3、sequence</dt>

在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),

而在Interbase中使用生成器(generator)。傳回的辨別符是int類型的。

<dt>  4、hilo</dt>

  使用一個高/低位算法來高效的生成int類型的辨別符。給定一個表和字段(預設分别是是hibernate_unique_key

和next_hi)作為高位值得來源。 高/低位算法生成的辨別符隻在一個特定的資料庫中是唯一的。在使用者自行提供的連接配接中,不要使用這種生成器。

<dt>  5、seqhilo</dt>

使用一個高/低位算法來高效的生成int類型的辨別符,給定一個資料庫序列(sequence)的名字。

<dt>  6、uuid.hex</dt>

用一個System.Guid的ToString()方法法生成字元串類型的辨別符,

字元串的長度由format參數定義。

<dt>  7、uuid.string</dt>

用一個新的System.Guid執行個體的byte[]轉化為字元串作為标示符。

<dt>  8、guid</dt>

使用新的System.Guid執行個體作為标示符。

<dt>  9、guid.comb</dt>

使用Jimmy

Nilsson的算法(請參閱http://www.informit.com/articles/article.asp?p=25862)生成一個新的System.Guid标示符。

<dt>  10、native</dt>

根據底層資料庫的能力選擇identity, sequence 或者hilo中的一個。

<dt>  11、assigned</dt>

讓應用程式在 Save()之前為對象配置設定一個标示符。

<dt>  12、foreign</dt>

使用另外一個相關聯的對象的辨別符。通常和&lt;one-to-one&gt;聯合起來使用。

  hilo 和 seqhilo生成器給出了兩種hi/lo算法的實作, 這是一種很令人滿意的辨別符生成算法。

第一種實作需要一個“特殊”的資料庫表來儲存下一個可用的“hi”值。 第二種實作使用一個Oracle風格的序列(在被支援的情況下)。

很不幸,你在為NHibernate自行提供IDbConnection時無法使用hilo。

NHibernate必須能夠在一個事務裡擷取"hi"值。

   UUID算法是調用Guid.NewGuid().ToString(format)方法生成标示符。 format參數的使用請參閱MSDN,GUID的預設分隔符是-,

這個基本不會改動。format可以決定是都替換預設的預設分隔符。 The UUID

is generated by callingGuid.NewGuid().ToString(format)。

   這個算法調用Guid.NewGuid().ToByteArray()方法擷取byte[], 然後将byte[]轉換為char[]。char[]被作為一個長度 為16的字元串傳回。

   guid标示符通過調用 Guid.NewGuid()建立。當在MSSQL中使用Guids标示符時做主鍵,外鍵或者是索引是為了擷取更好的性能

通常使用 guid.comb。其他支援GUIDs标示的的資料庫使用guid.comb能否獲得性能的提升未知。

  對于内部支援辨別字段的資料庫(DB2,MySQL,Sybase,MS SQL),你可以使用identity關鍵字生成。

對于内部支援序列的資料庫(DB2,Oracle, PostgreSQL, Interbase, McKoi,SAP DB),

你可以使用sequence風格的關鍵字生成。 這兩種方式對于插入一個新的對象都需要兩次SQL查詢。

對于跨平台開發,native政策會從identity, sequence

和hilo中進行選擇,選擇哪一個,這取決于底層資料庫的支援能力。

  如果你需要應用程式配置設定一個标示符(而非NHibernate來生成它們),你可以使用assigned生成器。

這種特殊的生成器會使用已經配置設定給對象的辨別符屬性的辨別符值。用這種特性來配置設定商業行為的關鍵字要特别小心(基本上總是一種可怕的設計決定)。

  因為其繼承天性,使用這種生成器政策的實體不能通過ISession的SaveOrUpdate()方法儲存。作為替代,

你應該明确告知NHibernate是應該被save還是update,分别調用ISession的Save()或Update()方法。

 如果表使用聯合主鍵,你可以把類的多個屬性組合成為辨別符屬性。&lt;composite-id&gt; 元素接受&lt;key-property&gt;屬性映射和&lt;key-many-to-one&gt;屬性映射作為子元素。

  你的持久化類必須重載 Equals()和GetHashCode()方法,來實作組合的辨別符判斷等價.也必須實作可序列化。

  不幸的是,這種組合關鍵字的方法意味着一個持久化類是它自己的辨別。除了對象自己之外,

沒有什麼友善的“把手”可用。你必須自己初始化持久化類的執行個體,在使用組合關鍵字load()持久化狀态之前,

必須填充他的聯合屬性。我們會在第 7.4 節 “元件作為聯合辨別符(Components as composite

identifiers)”章中說明一種更加友善的方法, 把聯合辨別實作為一個獨立的類,下面描述的屬性隻對這種備用方法有效:

name (可選):一個元件類型,持有聯合辨別(參見下一節)。

NHibernate應該使用的通路此屬性值的政策

class (可選 - 預設為通過反射(reflection)得到的屬性類型) :

作為聯合辨別的元件類名(參見下一節)。