NHibernate从入门到精通系列(6)——基本映射

 

  内容摘要

  映射定义概括

  基本映射常用标签

  NHibernate的类型

 

  一、映射定义概括

  1.1 映射定义(Mapping declaration)

  对象和关系数据库之间的映射是用一个XML文档(XML document)来定义的。这个映射文档被设计为易读的,并且可以手工修改。映射语言是以对象为中心的, 意味着映射是按照持久化类的定义来创建的,而非表的定义。

  让我们打开上节课的映射例子:

  

Product.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>

<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, SybaseHypersonicSQL的内置标识字段提供支持。数据库返回的主键值 返回的标识符是int类型的。

 

N

sequence

DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在Interbase中使用生成器(generator)。返回的标识符是int类型的。

Y

seqhilo

使用一个高/低位算法来高效的生成int类型的标识符,给定一个数据库序列(sequence)的名字。

N

uuid.hex

用一个System.GuidToString()方法法生成字符串类型的标识符, 字符串的长度由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()方法。例子如下:

 

<?xml version="1.0" encoding="utf-8" ?>

<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;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Domain
{
    
public class Product
    {
        
public virtual ProductID ID { getset; }

        
public virtual string Unit { getset; }

        
public virtual decimal SellPrice { getset; }

        
public virtual decimal BuyPrice { getset; }

        
public virtual string Remark { getset; }
    }

    
public class ProductID
    {
        
public virtual string Name { getset; }

        
public virtual string QuantityPerUnit { getset; }

        
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

  欢迎转载,但需保留版权。

posted @ 2011-02-24 00:21  冬子哥  阅读(19753)  评论(17编辑  收藏  举报