被映射的类必须声明对应数据库表主键字段。大多数类有一个属性,为每一个实例包含唯一的标识。 <id> 元素定义了该属性到数据库表主键字段的映射。
<id
name="propertyName" (1)
type="typename" (2)
column="column_name" (3)
unsaved-value="any|none|null|id_value" (4)
access="field|property|nosetter|ClassName"> (5)
<generator class="generatorClass"/>
</id>
(1) name (可选): 标识属性的名字。
(2) type (可选): 标识NHibernate类型的名字。
(3) column (可选 - 默认为属性名): 主键字段的名字。
(4) unsaved-value (可选 - 默认为 null): 一个特定的标识属性值,用来标志该实例是刚刚创建的,尚未保存。这可以把这种实例和从以前的session中装载过(可能又做过修改--译者注)但未再次持久化的实例区分开来。
(5) access (可选 - 默认为 property): NHibernate用来访问属性值的策略。
如果name属性不存在,会认为这个类没有标识属性。
unsaved-value 属性很重要!如果你的类的标识属性不是默认为null的,你应该指定正确的默认值。特别重要的是在使用值类型System.ValueType例如System.Int32 或者 System.Guid作为你的<id>属性时确保清楚的设置这个属性,因为System.ValueType对象不可能为null值。
还有一个另外的<composite-id>声明可以访问旧式的多主键数据。我们强烈不鼓励使用这种方式。
generator必须声明的 <generator> 子元素是一个.NET类的名字,用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数,用 <param>元素来传递。
<id name="Id" type="Int64" column="uid" unsaved-value="0">
<generator class="NHibernate.Id.TableHiLoGenerator">
<param name="table">uid_table</param>
<param name="column">next_hi_value_column</param>
</generator>
</id>
所有的生成器都实现NHibernate.Id.IdentifierGenerator接口。这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然,NHibernate提供了很多内置的实现。下面是一些内置生成器的快捷名字:
identity 对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。返回的标识符是 Int64, Int32 或者 Int16类型的。
sequence(序列)
对DB2,MySQL, PostgreSQL, Oracle的内置标识字段提供支持。返回的标识符是Int64 Int32 或者 Int16类型的。
hilo(高低位) 使用一个高/低位算法来高效的生成Int64, Int32 或者 Int16类型的标识符。给定一个表和字段(默认分别是hibernate_unique_key 和next)作为高位值得来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
seqhilo(使用序列的高低位) 使用一个高/低位算法来高效的生成Int64, Int32 或者 Int16类型的标识符,给定一个数据库序列(sequence)的名字。
uuid.hex 用一个System.Guid和它的ToString(string format)方法生成字符串类型的标识符。字符串的长度取决于 format的配置。
uuid.string 用一个新的System.Guid产生一个byte[] ,把它转换成字符串。
guid 用一个新的System.Guid 作为标识符。
guid.comb 用Jimmy Nilsson在文章
http://www.informit.com/articles/article.asp?p=25862 中描述的算法产生一个新的System.Guid。
native(本地) 根据底层数据库的能力选择 identity, sequence 或者 hilo中的一个。
assigned(程序设置) 让应用程序在save()之前为对象分配一个标示符。
foreign(外部引用) 使用另外一个相关联的对象的标识符。和<one-to-one>联合一起使用。
高/低位算法(Hi/Lo Algorithm)hilo 和 seqhilo生成器给出了两种hi/lo算法的实现,这是一种很令人满意的标识符生成算法。第一种实现需要一个“特殊”的数据库表来保存下一个可用的“hi”值。第二种实现使用一个Oracle风格的序列(在被支持的情况下)。
<id name="Id" type="Int64" column="cat_id">
<generator class="hilo">
<param name="table">hi_value</param>
<param name="column">next_value</param>
<param name="max_lo">100</param>
</generator>
</id>
<id name="Id" type="Int64" column="cat_id">
<generator class="seqhilo">
<param name="sequence">hi_value</param>
<param name="max_lo">100</param>
</generator>
</id>
很不幸,你在为NHibernate自行提供Connection的时候无法使用hilo 。Hibernate必须能够在一个新的事务中得到一个"hi"值。
UUID Hex 算法
<id name="Id" type="String" column="cat_id">
<generator class="uuid.hex">
<param name="format">format_value</param>
<param name="seperator">seperator_value</param>
</generator>
</id>
UUID是通过调用Guid.NewGuid().ToString(format)产生的。format值的设置请参考MSDN文档。默认的seperator很少也不应该被改变。format决定是否配置好的seperator 能替换默认的seperator,并提供给自己使用(译者注:此句可能和原文有出入,请参见英文文档)。
UUID String 算法UUID是通过调用 Guid.NewGuid().ToByteArray() 并且把 byte[]转换成char[],char[] 做为一个16个字符组成的字符串返回。
GUID 算法guid 标识符通过调用Guid.NewGuid()产生。 为了提升Guids在MS SQL中作为主键,外键和索引的一部分时的性能,可以使用guid.comb。在别的数据库中使用guid.comb的好处是支持非标准的GUID。
标识字段和序列(Identity columns and Sequences)对于内部支持标识字段的数据库(DB2,MySQL,Sybase,MS SQL),你可以使用identity关键字生成。对于内部支持序列的数据库(DB2,Oracle, PostgreSQL),你可以使用sequence风格的关键字生成。这两种方式对于插入一个新的对象都需要两次SQL查询。当使用MS SQL并且采用identity主键生成器,select SCOPE_IDENTITY()将会被附加到insert的sql语句,因而不可避免的执行两个不同的IDbCommand。
<id name="Id" type="Int64" column="uid">
<generator class="sequence">
<param name="sequence">uid_sequence</param>
</generator>
</id>
<id name="Id" type="Int64" column="uid" unsaved-value="0">
<generator class="identity"/>
</id>
对于跨平台开发,native策略会从identity, sequence 和hilo中进行选择,取决于底层数据库的支持能力。
程序分配的标识符(Assigned Identifiers)如果你需要应用程序分配一个标示符(而非NHibernate来生成它们),你可以使用assigned生成器。这种特殊的生成器会使用已经分配给对象的标识符属性的标识符值。用这种特性来分配商业行为的关键字要特别小心(基本上总是一种可怕的设计决定)。
因为其继承天性,使用这种生成器策略的实体不能通过ISession的SaveOrUpdate()方法保存。作为替代,你应该明确告知NHibernate是应该被save还是update,分别调用ISession的Save()或Update()方法。
顶部