NHibernate从入门到精通系列(6)——基本映射
内容摘要
映射定义概括
基本映射常用标签
NHibernate的类型
一、映射定义概括
1.1 映射定义(Mapping declaration)
对象和关系数据库之间的映射是用一个XML文档(XML document)来定义的。这个映射文档被设计为易读的,并且可以手工修改。映射语言是以对象为中心的, 意味着映射是按照持久化类的定义来创建的,而非表的定义。
让我们打开上节课的映射例子:
Product.hbm.xml 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain">
<class name="Product" table="T_Product" lazy="true" >
<id name="ID" column="ID" type="Guid" >
<generator class="assigned" />
</id>
<property name="Code" type="string">
<column name="Code" length="50"/>
</property>
<property name="Name" type="string">
<column name="Name" length="50"/>
</property>
<property name="QuantityPerUnit" type="string">
<column name="QuantityPerUnit" length="50"/>
</property>
<property name="Unit" type="string">
<column name="Unit" length="50"/>
</property>
<property name="SellPrice" type="decimal">
<column name="SellPrice" precision="14" scale="2"/>
</property>
<property name="BuyPrice" type="decimal">
<column name="BuyPrice" precision="14" scale="2"/>
</property>
<property name="Remark" type="string">
<column name="Remark" length="200"/>
</property>
</class>
</hibernate-mapping>
其中xmlns为xml命名空间,我们能够在NHibernate的分发包src\nhibernate-mapping.xsd里找到XSD文件。我们可以将.xsd文件拷贝到Visual Studio安装目录的\Xml\Schemas中,以便带来NHibernate持久化类配置的提示功能。
二、基本映射常用标签
作为NHibernate这个ORM框架来说,一个实体类对应的是数据库中的一张表;类中的一个属性对应表中的一个字段;一个对象对应的是表中的一条记录。
2.1 hibernate-mapping
<hibernate-mapping>标签是NHibernate映射文件的根节点。
  <hibernate-mapping                                   
       schema="schemaName"                         数据库schema名称。
default-cascade="none|save-update" 默认的级联风格,(可选 - 默认为 none):。
auto-import="true|false" 指定我们在使用查询语句的时候是否可以使用非全限定名。
assembly="AssemblyName"
namespace="Namespace" 指定映射文件中的类的应用程序集名称和其所在的名称空间名,用来生成类的非全限定名。
/>
2.2 class
<class>标签是定义一个持久化类的。
  <class                                               
       name="ClassName"                              持久化类的类名,这里可以是类的全名。
        table="tableName"                             对应的数据库表名。
        discriminator-value="discriminator_value"     辨别值,一个用于区分不同的子类的值,在多态行为时使用(在后面继承映射的课程中会讲到)。
        mutable="true|false"                          表明该类的实例可变。
        schema="owner"                                覆盖在根元素中指定的schema名字。
        proxy="ProxyInterface"                        指定一个接口,在延迟装载时作为代理使用。你可以在这里使用该类自己的名字。
        dynamic-update="true|false"                   指定用于UPDATE 的SQL将会在运行时动态生成,并且只更新那些改变过的字段。
        dynamic-insert="true|false"                   指定用于 INSERT的 SQL 将会在运行时动态生成,并且只包含那些非空值字段。
        select-before-update="true|false"             指定NHibernate除非确定对象的确被修改了,UPDATE操作。
        polymorphism="implicit|explicit"              界定是隐式还是显式的使用查询多态。
        where="arbitrary sql where condition"         指定一个附加的SQL WHERE 条件,在抓取这个类的对象时会一直增加这个条件。
        persister="PersisterClass"                    指定一个定制的 IClassPersister。
        batch-size="N"                                指定一个用于根据标识符抓取实例时使用的"batch size"(批次抓取数量),默认值为1。 
        optimistic-lock="none|version|dirty|all"      乐观锁定,决定乐观锁定的策略。
        lazy="true|false"                             是否启用延迟加载。
        abstract="true|false"                         是否为抽象类。
  /> 
2.3 id
<id>标签定义了该属性到数据库表主键字段的映射。
<id
    name="PropertyName"                                   标识属性的名字。
        type="typename"                                          NHibernate类型的名字
        column="column_name"                                主键字段的名字。
        unsaved-value="any|none|null|id_value"         一个特定的标识属性值,用来标志该实例是刚刚创建的,尚未保存。
        access="field|property|nosetter|ClassName"    NHibernate用来访问属性值的策略。
        <generator class="generatorClass"/>
  </id>
generator:主键生成策略。NHibernate提供了以下几种生成策略:
| 
 名称  | 
 说明  | 
 是否常用  | 
| 
 increment  | 
 用于为int类型生成 唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用  | 
 N  | 
| 
 identity  | 
 对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。数据库返回的主键值 返回的标识符是int类型的。   | 
 N  | 
| 
 sequence  | 
 在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是int类型的。  | 
 Y  | 
| 
 seqhilo  | 
 使用一个高/低位算法来高效的生成int类型的标识符,给定一个数据库序列(sequence)的名字。  | 
 N  | 
| 
 uuid.hex  | 
 用一个System.Guid的ToString()方法法生成字符串类型的标识符, 字符串的长度由format参数定义。  | 
 N  | 
| 
 uuid.string  | 
 用一个新的System.Guid实例的byte[]转化为字符串作为标示符。  | 
 N  | 
| 
 guid  | 
 使用新的System.Guid实例作为标示符。  | 
 | 
| 
 guid.comb  | 
 使用Jimmy Nilsson的算法生成一个新的System.Guid标示符。  | 
 | 
| 
 native  | 
 根据底层数据库的能力选择identity, sequence 或者hilo中的一个。  | 
 Y  | 
| 
 assigned  | 
 让应用程序在 Save()之前为对象分配一个标示符。  | 
 Y  | 
| 
 foreign  | 
 使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。  | 
 Y  | 
2.4 composite-id
<composite-id>为联合主键。
  <composite-id                                                        
        name="PropertyName"                                                            
        class="ClassName"                                               联合主键类的类名。
        unsaved-value="any|none"                                   
        access="field|property|nosetter|ClassName">
        <key-property name="PropertyName" type="typename" column="column_name"/>             联合主键的属性
        <key-many-to-one name="PropertyName class="ClassName" column="column_name"/>      联合主键多对一属性
        ......
  </composite-id>
注意的是,若使用联合主键,你的持久化类必须重载 Equals()和GetHashCode()方法。例子如下:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain">
<class name="Product" table="T_Product" lazy="true" >
<composite-id name="ID" class="ProductID">
<key-property name="Name" type="string">
<column name="Name" length="50"/>
</key-property>
<key-property name="QuantityPerUnit" type="string">
<column name="QuantityPerUnit" length="50"/>
</key-property>
</composite-id>
<property name="Unit" type="string">
<column name="Unit" length="50"/>
</property>
<property name="SellPrice" type="decimal">
<column name="SellPrice" precision="14" scale="2"/>
</property>
<property name="BuyPrice" type="decimal">
<column name="BuyPrice" precision="14" scale="2"/>
</property>
<property name="Remark" type="string">
<column name="Remark" length="200"/>
</property>
</class>
</hibernate-mapping>
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Domain
{
public class Product
{
public virtual ProductID ID { get; set; }
public virtual string Unit { get; set; }
public virtual decimal SellPrice { get; set; }
public virtual decimal BuyPrice { get; set; }
public virtual string Remark { get; set; }
}
public class ProductID
{
public virtual string Name { get; set; }
public virtual string QuantityPerUnit { get; set; }
public override bool Equals(object obj)
{
var entity = obj as ProductID;
if (entity == null)
{
return false;
}
return entity.Name == this.Name
&& entity.QuantityPerUnit == this.QuantityPerUnit;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
运行效果如图2.4.1所示,包含联合主键的表已经生成成功。

图2.4.1
2.5 property
<property>标签是类定义了一个持久化类的属性。
  <property
        name="propertyName"                          属性名
        column="column_name"                        对应的数据库字段名。
        type="typename"                                 NHibernate类型的名字。
        update="true|false"                              update时是否包含该字段。
        insert="true|false"                                insert时时候包含该字段。
        formula="arbitrary SQL expression"       一个SQL表达式,定义了这个计算 (computed) 属性的值。计算属性没有和它对应的数据库字段
        access="field|property|ClassName"        NHibernate用来访问属性值的策略。
        optimistic-lock="true|false"                   乐观锁定
        generated="never|insert|always"           表明此属性值是否是由数据库生成。
  />
三、NHibernate的类型
3.1 值类型映射表
| 
 NHibernate类型   | 
 .NET类型   | 
 Database类型   | 
 备注   | 
| 
 AnsiChar   | 
 System.Char   | 
 DbType.AnsiStringFixedLength - 1 char   | 
    | 
| 
 Boolean   | 
 System.Boolean   | 
 DbType.Boolean   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Byte   | 
 System.Byte   | 
 DbType.Byte   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Char   | 
 System.Char   | 
 DbType.StringFixedLength - 1 char   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 DateTime   | 
 System.DateTime   | 
 DbType.DateTime - ignores the milliseconds   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Decimal   | 
 System.Decimal   | 
 DbType.Decimal   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Double   | 
 System.Double   | 
 DbType.Double   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Guid   | 
 System.Guid   | 
 DbType.Guid   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Int16   | 
 System.Int16   | 
 DbType.Int16   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Int32   | 
 System.Int32   | 
 DbType.Int32   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Int64   | 
 System.Int64   | 
 DbType.Int64   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 PersistentEnum   | 
 System.Enum   | 
 潜在类型对应的DbType   | 
 不用在映射文件指定type="PersistentEnum".而是提供枚举的程序集全名, 让NHibernate用反射来猜测类型。枚举使用的潜在类型决定适当的DbType.。   | 
| 
 Single   | 
 System.Single   | 
 DbType.Single   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Ticks   | 
 System.DateTime   | 
 DbType.Int64   | 
 type="Ticks"必须被指定。   | 
| 
 TimeSpan   | 
 System.TimeSpan   | 
 DbType.Int64   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Timestamp   | 
 System.DateTime   | 
 DbType.DateTime - 取决于数据库支持   | 
 type="Timestamp"必须被指定。   | 
| 
 TrueFalse   | 
 System.Boolean   | 
 DbType.AnsiStringFixedLength - 一个字符,'Y' 或者'N'   | 
 type="TrueFalse"必须被指定。   | 
| 
 YesNo   | 
 System.Boolean   | 
 DbType.AnsiStringFixedLength - 一个字符,'Y' 或者'N'   | 
 type="YesNo"必须被指定。   | 
3.2 应用类型映射表
| 
 NHibernate Type   | 
 .NET Type   | 
 Database Type   | 
 Remarks   | 
| 
 AnsiString   | 
 System.String   | 
 DbType.AnsiString   | 
 type="AnsiString"必须被指定。   | 
| 
 CultureInfo   | 
 System.Globalization.CultureInfo   | 
 DbType.String - 表明文化(culture)的5个字符  | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Binary   | 
 System.Byte[]   | 
 DbType.Binary   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 Type   | 
 System.Type   | 
 DbType.String 保存应用程序集权限定名。   | 
 在没有指定类型(type) 属性时的默认值。   | 
| 
 String   | 
 System.String   | 
 DbType.String   | 
 在没有指定类型(type) 属性时的默认值。   | 
3.3 二进制类型映射表
| 
 NHibernate Type   | 
 .NET Type   | 
 Database Type   | 
 Remarks   | 
| 
 StringClob   | 
 System.String   | 
 DbType.String   | 
 type="StringClob"必须被指定。 整个字段在内存里可读。   | 
| 
 BinaryBlob   | 
 System.Byte[]   | 
 DbType.Binary   | 
 type="BinaryBlob"必须被指定。 整个字段在内存里可读。   | 
| 
 Serializable   | 
 Any System.Object 必须标注可序列化标签   | 
 DbType.Binary   | 
 type="Serializable" 应该被指定. 如果不能为属性找到NHibernate类型,这是最后可依靠的类型。   | 
出处:http://www.cnblogs.com/GoodHelper/archive/2011/02/24/nhibernate06.html
欢迎转载,但需保留版权。
                    
                

                
            
        
浙公网安备 33010602011771号