六、鉴别器

   在"一棵对象继承树对应一个表"的策略中,<discriminator>元素是必需的, 它定义了表的鉴别器字段。 鉴别器字段包含标志值,用于告知持久化层应该为某个特定的行创建哪一个子类的实例。 如下这些受到限制的类型可以使用: StringCharInt32,ByteShortBoolean , YesNoTrueFalse
<discriminator
column="discriminator_column"        (1)
type="discriminator_type"       (2)
force="true|false"       (3)
insert="true|false"       (4)
formula="arbitrary SQL expression"   (5)
/>
  说明:
(1)

column (可选 - 默认为 class) 鉴别器字段的名字

(2)

type (可选 - 默认为 String) 一个NHibernate字段类型的名字。

(3)

force(强制) (可选 - 默认为 false) "强制"NHibernate指定允许的鉴别器值,即使当取得的所有实例都是根类的。

(4)

insert (可选 - 默认为true) 如果你的鉴别器字段也是映射为复合标识(composite identifier)的一部分, 则需将 这个值设为false。

(5)

formula (可选) 一个SQL表达式,在类型判断(判断是父类还是具体子类-译注)时执行。可用于基于内容的鉴别器。

  鉴别器字段的实际值是根据discriminator-value 和<class> and <subclass>元素中 的discriminator-value属性得来的。

  force属性仅仅在这种情况下有用的:表中包含没有被映射到持久化类的附加辨别器值。 这种情况不会经常遇到。

  使用formula属性你可以定义一个SQL表达式,用来判断一个行数据的类型。

<discriminator formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end" type="Int32"/>

七、版本(version)(可选)

  <version>元素是可选的,表明表中包含附带版本信息的数据。 这在你准备使用 长事务(long transactions)的时候特别有用。
<version
column="version_column" (1)
name="PropertyName" (2)
type="typename" (3)
access="field|property|nosetter|ClassName" (4)
unsaved-value="null|negative|undefined|value" (5)
generated="never|always" (6)
/>

  说明:

(1)

column (可选 - 默认为属性名): 指定持有版本号的字段名。

(2)

name 持久化类的属性名。

(3)

type (可选 - 默认是 Int32): 版本号的类型。

(4)

access (可选 - 默认是 property): NHibernate用于访问属性值的策略。

(5)

unsaved-value(可选 - 默认是undefined): 用于标明某个实例时刚刚被实例化的(尚未保存)版本属性值, 依靠这个值就可以把这种情况 和已经在先前的session中保存或装载的脱管(detached)实例区分开来。 (undefined指明应被使用的标识属性值。)

(6)

generated(可选 - 默认是 never): 表明此版本属性值是否实际上是由数据库生成的。 请参阅 5.5  “数据库生成属性(Generated Properties)”部分的讨论。

版本号必须是以下类型:Int64Int32Int16Ticks,或者 TimestampTimeSpan

八、timestamp (可选)

  可选的<timestamp>元素指明了表中包含时间戳数据。 这用来作为版本的替代。 时间戳本质上是一种对乐观锁定的一种不是特别安全的实现。当然, 有时候应用程序可能在其他方面使用时间戳。
<timestamp
column="timestamp_column"        (1)
name="PropertyName"      (2)
access="field|property|nosetter|ClassName" (3)
unsaved-value="null|undefined|value"      (4)
generated="never|always"       (5)
/>

 说明:

(1)

column(可选 - 默认为属性名): 持有时间戳的字段名。

(2)

name: 在持久化类中的.NE风格的属性名, 其.NE类型是 DateTime的。

(3)

access (可选 - 默认是 property): NHibernate用于访问属性值的策略。

(4)

unsaved-value (可选 - 默认是null): 用于标明某个实例时刚刚被实例化的(尚未保存)版本属性值, 依靠这个值就可以把这种情况和 已经在先前的session中保存或装载的脱管(detached)实例区分开来。 (undefined 指明使用标识属性值进行这种判断。)

(5)

generated : 指出时间戳值是否实际上是由数据库生成的.请参阅5.5  “数据库生成属性(Generated Properties)”的讨论。

  注意<timestamp>等价于 <version type="timestamp">

九、property

  <property>元素为类定义了一个持久化类的属性。

<property
name="propertyName" (1)
column="column_name" (2)
type="typename" (3)
update="true|false" (4)
insert="true|false" (4)
formula="arbitrary SQL expression" (5)
access="field|property|ClassName" (6)
optimistic-lock="true|false" (7)
generated="never|insert|always" (8)
/>

 说明:

(1)

name: 属性的名字。

(2)

column (可选 - 默认为属性名字): 对应的数据库字段名。

(3)

type (可选): 一个NHibernate类型的名字。

(4)

update, insert (可选 - 默认为 true) : 表明用于UPDATE 和/或 INSERT 的SQL语句中是否包含这个被映射了的字段。 这二者如果都设置为false 则表明这是一个“外源性(derived)”的属性, 它的值来源于映射到同一个(或多个) 字段的某些其他属性,或者通过一个trigger(触发器)或其他程序生成。

(5)

formula (可选): 一个SQL表达式,定义了这个计算 (computed) 属性的值。计算属性没有和它对应的数据库字段。

(6)

access (可选 - 默认值为 property): NHibernate用来访问属性值的策略。

(7)

optimistic-lock (可选 - 默认为 true): 指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。

(8)

generated (可选 - 默认为 never): 表明此属性值是否实际上是由数据库生成的。 请参阅5.5  “数据库生成属性(Generated Properties)”的讨论。

 typename可以是如下几种

  1. NHibernate基本类型名(比如:Int32, String, Char, DateTime, Timestamp, Single, Byte[], Object, ...)。

  2. 一个.Net类的名字,这个类属于一种默认基础类型 (比如: System.Int16, System.Single, System.Char, System.String, System.DateTime, System.Byte[], ...)。

  3. 一个枚举类型的名字。(比如:. eg.Color)。

  4. 一个可以序列化的.NET类的名字。

  5. 一个自定义类型的类的名字。(比如: Illflow.Type.MyCustomType)。

  注意你必须为所有类型(除了NHibernate基础类型)指定完整的应用程序集权限定名 (或者是在<hibernate-mapping>里面配置了assemblynamespace属性)。

  NHibernate支持.NET 2.0的可空类型,这些类型和对应的非可空类型处理方式是一致的, 例如:Nullable<Int32>可以对应type="Int32"或者是type="System.Int32"

  如果你没有指定类型,NHibernate会使用反射来得到这个名字的属性, 以此来猜测正确的NHibernate类型。NHibernate会对属性读取器(getter方法)的返回类进行解释, 按照规则2,3,4的顺序。然而,这并不足够。 在某些情况下你仍然需要type属性。 (比如,为了区别NHibernateUtil.DateTimeNHibernateUtil.Timestamp,或者为了指定一个自定义类型。)

  access属性用来让你控制NHibernate如何在运行时访问属性。 在默认情况下, NHibernate会按照access-strategy.naming-strategy来格式化属性名 .naming-strategy不是必填项。

 表 5.1. 访问策略

访问策略名 描述
property

默认实现:NHibernate访问类的set/get属性,这种方式没有命名策略,因为name就代表属性的名称。

field

NHibernate将会直接访问成员变量。NHibernate使用name作为成员变量的名称。 当对象属性的get和set里面有额外的操作,而你不想让NHibernate设置或者读取对象时执行额外的操作, 可以用这个策略。当你使用HQL时需要属性名而非字段时,就需要命名策略(Naming Strateg)。

nosetter

NHibernate将会在设置值时直接访问字段,获得值时访问属性。 当API使用者不能直接改变值,因而只为属性只提供了get访问器时, 你可以用这个策略。NHibernate使用name属性(attribute)作为属性(Property ), 并且需要提供字段名,所以命名策略必须(Naming Strategy)使用。

ClassName

如果NHibernate内置的访问策略(Access Strategie)不能满足你的要求。 你可以通过实现NHibernate.Property.IPropertyAccessor接口来自己的访问策略(Access Strategie)。 这个值需要用程序集名(Assembly)来限定,这样就能通过 Activator.CreateInstance(string AssemblyQualifiedName)来读取。

  命名策略(Naming Strategy)

命名策略 描述
camelcase

name属性被转换CamelCase格式来查找字段。<property name="Foo" ... >使用foo字段。

camelcase-underscore

name属性被转换CamelCase格式并添加下划线前缀来查找字段。<property name="Foo" ... >使用_foo字段。

lowercase

name属性被转换小写格式来查找字段。<property name="FooBar" ... > 使用 foobar字段.

lowercase-underscore

name属性被转换小写格式并添加下划线前缀来查找字段。<property name="FooBar" ... >使用_foobar字段.

pascalcase-underscore

name属性添加下划线前缀来查找字段。<property name="Foo" ... >使用_Foo字段。

pascalcase-m

name属性添加字母m前缀来查找字段。<property name="Foo" ... >使用mFoo字段。

pascalcase-m-underscore

name属性添加字母m和下划线前缀来查找字段。<property name="Foo" ... > 使用m_Foo字段。

 

十、多对一(many-to-one)

   通过 many-to-one元素,可以定义一种常见的与另一个持久化类的关联。这种关系模型是多对一关联。(实际上是一个对象引用。)
<many-to-one
name="PropertyName" (1)
column="column_name" (2)
class="ClassName" (3)
cascade="all|none|save-update|delete" (4)
fetch="join|select" (5)
update="true|false" (6)
insert="true|false" (6)
property-ref="PropertyNameFromAssociatedClass" (7)
access="field|property|nosetter|ClassName" (8)
unique="true|false" (9)
optimistic-lock="true|false" (10)
not-found="ignore|exception" (11)
/>

  说明:

(1)

name:属性名。

(2)

column数据库字段名

(3)

class(可选 - 默认是通过反射得到属性类型): 关联的类的名字。

(4)

cascade(级联) (可选): 指明哪些操作会从父对象级联到关联的对象。

(5)

fetch (可选 - 默认为 select): 在外连接抓取(outer-join fetching)和序列选择抓取(sequential select fetching)两者中选择其一。

(6)

(可选 - defaults to true) 指定对应的字段是否包含在用于UPDATE 和/或 INSERT 的SQL语句中。如果二者都是false,则这是一个纯粹的 “外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到 或者通过trigger(触发器)、或其他程序。

(7)

property-ref: (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。 如果没有指定,会使用对方关联类的主键。

(8)

access(可选 - 默认是 property): NHibernate用来访问属性的策略。

(9)

unique (可选): 使用DDL为外键字段生成一个唯一约束。此外, 这也可以用作property-ref的目标属性。这使关联同时具有 一对一的效果。

(10)

optimistic-lock (可选 - 默认为 true): 指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。

(11)

not-found (可选 - 默认为 exception): 指定外键引用的数据不存在时如何处理: ignore会将数据不存在作为关联到一个空对象(null)处理。

  cascade属性允许下列值:: all, save-update, delete, none. 设置除了none以外的其它值会传播特定的操作到关联的(子)对象中。参见后面的“Lifecycle Objects(自动管理生命周期的对象)”。

  fetch参数允许下列两个不同值:

  • join外连接抓取

  • select使用隔离查询抓取

  一个典型的简单many-to-one 定义例子:

<many-to-one name="product" class="Product" column="PRODUCT_ID"/>
  property-ref属性只应该用来对付老旧的数据库系统, 可能有外键指向对方关联表的是个非主键字段(但是应该是一个惟一关键字)的情况下。 这是一种十分丑陋的关系模型。比如说,假设Product类有一个惟一的序列号, 它并不是主键。(unique属性控制NHibernate通过SchemaExport工具生成DDL的过程。)
 
<property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>
那么关于OrderItem 的映射可能是:
 
 
<many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>
 当然,我们决不鼓励这种用法。
 
 

十一、一对一

   持久化对象之间一对一的关联关系是通过 one-to-one元素定义的。
<one-to-one
name="PropertyName" (1)
class="ClassName" (2)
cascade="all|none|save-update|delete" (3)
constrained="true|false" (4)
fetch="join|select" (5)
property-ref="PropertyNameFromAssociatedClass" (6)
access="field|property|nosetter|ClassName" (7)
/>

 说明:

(1)

name: 属性的名字。

(2)

class (可选 - 默认是通过反射得到的属性类型):被关联的类的名字。

(3)

cascade(级联) (可选) 表明操作是否从父对象级联到被关联的对象。

(4)

constrained(约束) (可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。 这个选项影响Save()和Delete()在级联执行时的先后顺序以及 决定该关联能否被委托(也在schema export tool中被使用).

(5)

fetch (可选 - 默认设置为select): 在外连接抓取或者序列选择抓取选择其一.

(6)

property-ref: (可选) 指定关联类的属性名,这个属性将会和本类的主键相对应。如果没有指定,会使用对方关联类的主键。

(7)

access (可选 - 默认是 property): NHibernate用来访问属性的策略。

  有两种不同的一对一关联:

  • 主键关联

  • 惟一外键关联

  主键关联不需要额外的表字段;如果两行是通过这种一对一关系相关联的,那么这两行就共享同样的主关键字值。所以如果你希望两个对象通过主键一对一关联,你必须确认它们被赋予同样的标识值!

  比如说,对下面的Employee和Person进行主键一对一关联:

<one-to-one name="Person" class="Person"/>
<one-to-one name="Employee" class="Employee" constrained="true"/>

  现在我们必须确保PERSON和EMPLOYEE中相关的字段是相等的。我们使用一个被成为foreign的特殊的现在我们必须确保PERSON和EMPLOYEE中相关的字段是相等的。我们使用一个被成为foreign的特殊的hibernate标识符生成策略:标识符生成策略: foreign:

<class name="Person" table="PERSON">
<id name="Id" column="PERSON_ID">
<generator class="foreign">
<param name="property">Employee</param>
</generator>
</id>
...
<one-to-one name="Employee"
class="Employee"
constrained="true"/>
</class>

  一个刚刚保存的Person实例被赋予和该Person的employee属性所指向的Employee实例同样的关键字值。

另一种方式是一个外键和一个惟一关键字对应,上面的Employee和Person的例子,如果使用这种关联方式,可以表达成:

<many-to-one name="Person" class="Person" column="PERSON_ID" unique="true"/>

 如果在Person的映射加入下面几句,这种关联就是双向的:

<one-to-one name="Employee" class="Employee" property-ref="Person"/>
 

NHibernate之映射文件配置说明(转载2)的更多相关文章

  1. NHibernate之映射文件配置说明

    NHibernate之映射文件配置说明 1. hibernate-mapping 这个元素包括以下可选的属性.schema属性,指明了这个映射所引用的表所在的schema名称.假若指定了这个属性, 表 ...

  2. NHIBERNATE之映射文件配置说明(转载4)

    二十.自定义值类型   开发者创建属于他们自己的值类型也是很容易的.比如说,你可能希望持久化Int64类型的属性, 持久化成为VARCHAR 字段.NHibernate没有内置这样一种类型.自定义类型 ...

  3. NHibernate之映射文件配置说明(转载3)

    十二.组件(component), 动态组件(dynamic-component) <component>元素把子对象的一些元素与父类对应的表的一些字段映射起来. 然后组件可以定义它们自己 ...

  4. NHibernate之映射文件配置说明(转载1)

    源博客:http://www.cnblogs.com/kissdodog/archive/2013/02/21/2919886.html 1. hibernate-mapping 这个元素包括以下可选 ...

  5. [转]NHibernate之映射文件配置说明

    1. hibernate-mapping 这个元素包括以下可选的属性.schema属性,指明了这个映射所引用的表所在的schema名称.假若指定了这个属性, 表名会加上所指定的schema的名字扩展为 ...

  6. NHibernate初入门之映射文件配置说明(三)

    转载逆心http://www.cnblogs.com/kissdodog/archive/2013/02/21/2919886.html 1. hibernate-mapping 这个元素包括以下可选 ...

  7. NHibernate之映射文件配置说

    1. hibernate-mapping 这个元素包括以下可选的属性.schema属性,指明了这个映射所引用的表所在的schema名称.假若指定了这个属性, 表名会加上所指定的schema的名字扩展为 ...

  8. 使用代码辅助生成工具CodeSmith -- 生成NHibernate的映射文件

    首先下载CodeSmith工具:在百度云中,在CodeSmith文件夹中. 安装,使用激活工具激活. 然后下载NHibernate模板,也是在百度云中,在CodeSmith文件夹中. 之后直接点击NH ...

  9. 使用CodeSmith快速生成映射文件和映射类

    一 CodeSmith简介 本文以表自动生成NHibernate的映射文件和映射类的实例来说明一下本软件的使用方法. CodeSmith是一种基于模板的代码生成工具,其使用类似于ASP.NET的语法来 ...

随机推荐

  1. 自定义异常throw

    简单自定义一个年龄小于等于0,或者大于120会出现的异常 首先继承父类Exception,调用父类的构造器,这样才可以报出自己想要的异常 public class AgeException exten ...

  2. Qt5如何设置静态编译,解决生成的可执行文件打开出错问题

    将https://yunpan.cn/cqGGURjmG2fEY  访问密码 8de5  中的压缩包Qt5-MSVC-Static-master.zip 解压到你的qt安装目录,一般就是C:\Qt下, ...

  3. ios视图切换之push与present混用

    在变成过程中,经常遇到两个视图控制器之间的切换,导航控制器即UINaVigation是最常用的一种,有时为了某些效果又需要进行模态切换,即present. 我们的布局经常是在window上加一个nav ...

  4. 3.2 GUN as汇编(本文内容大部分引用原文,非原创)

    as86汇编仅仅用于编译内核中的boot/bootsect.s引导扇区程序和实模式下的设置程序boot/setup.s.内核中其余所有汇编语言程序(包括C语言产生的汇编程序)均使用gas来编译,并与C ...

  5. 移动端(html5)微信公众号下用keyup实时监控input值的变化无效

    搜索框依据用户输入的值实时检索,一开始自然而然想到keyup,在拼音状态时,啥问题也没有, 问题1:切换到中文输入法,问题出来了,keyup事件不灵便了,后来在网上搜了下,找到了思路, 问题2:微信公 ...

  6. C++ primer学习方法

    C++ primer学习:   第一次可以跳着看.关键是要尽快用起来,在使用中熟练,而不是在细节中迷失.   以C++ Primer第五版为例,第一遍读的时候: Part1也就是前七章,除了6.6,6 ...

  7. 转:pthread_detach()函数

    创建一个线程默认的状态是joinable. 如果一个线程结束运行但没有被join,则它的状态类似于进程中的Zombie Process,即还有一部分资源没有被回收(退出状态码). 所以创建线程者应该调 ...

  8. android:onclick属性

    android:onclick属性设置点击时从上下文中调用指定的方法,此时给指定一个方法名.例如: xml中: <Button android:layout_width="wrap_c ...

  9. windows 10是如何做到全平台统一的?

    1.EXE本身就是个容器,它可以在ARM平台上包含ARM的native code执行,也可以在x86平台上包含x86的native code执行,本质上无差别(所以麻烦那些说EXE不能在ARM平台上运 ...

  10. GitHub的使用详解!Windows GitHub ,Sublime Git GitGutter的使用!

    Github是什么? 它是代码管理工具. 在公司写的代码,不需要U盘拷贝回家,不需要放到网盘中.只需要上传到git上,就可以回家继续拷贝下来了. 比起svn要好, svn只适合局域网工作,离开局域网, ...