NHibernate——基本映射(5)
一、映射定义概括
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" cision ="14" scale ="2" />
</ property > < property name ="BuyPrice" type ="decimal" >
< column name ="BuyPrice" cision ="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="programlisting"> <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()方法。例子如下:
<? 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" cision ="14" scale ="2" />
</ property > < property name ="BuyPrice" type ="decimal" >
< column name ="BuyPrice" cision ="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 { 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 exssion" 一个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
欢迎转载,但需保留版权。
原文链接:http://www.cnblogs.com/GoodHelper/archive/2011/02/24/nhibernate06.html
NHibernate——基本映射(5)的更多相关文章
- NHibernate之映射文件配置说明
NHibernate之映射文件配置说明 1. hibernate-mapping 这个元素包括以下可选的属性.schema属性,指明了这个映射所引用的表所在的schema名称.假若指定了这个属性, 表 ...
- 牵一发动全身【Nhibernate基本映射】
用牵一发动全身来形容Nhibernate的映射,一点都不夸张.小小的属性的修改,决定了整个Nhibernate的执行动态.以下让我们来详细了解一下,通过回想我们在上篇文章中用到的配置文件,做一个对xm ...
- NHibernate 继承映射(第十六篇)
在NHibernate的映射中,关于继承的映射策略有3种方式 单表继承 类表继承 具体表继承 另外还有一种比较特别的多态映射 隐式多态 下面分别来阐述NHibernate继承映射的各种策略要点. 一. ...
- NHibernate 集合映射基础(第四篇) - 一对一、 一对多、多对多小示例
映射文件,用于告诉NHibernate数据库里的表.列于.Net程序中的类的关系.因此映射文件的配置非常重要. 一.一对一 NHibernate一对一关系的配置方式使用<one-to-one&g ...
- DDD中的值对象如何用NHibernate进行映射
原文:DDD中的值对象如何用NHibernate进行映射 <component/>是NHibernate中一个有趣的特性,即是用来映射DDD(Data-Display-Debuger)概念 ...
- 5、ASP.NET MVC入门到精通——NHibernate代码映射
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 上一篇NHibernate学习笔记—使用 NHibernate构建一个ASP.NET MVC应用程序 使用的是xml进行orm映射,那么这一 ...
- [NHibernate]关联映射
系列文章 [Nhibernate]体系结构 [NHibernate]ISessionFactory配置 [NHibernate]持久化类(Persistent Classes) [NHibernate ...
- [NHibernate]Nhibernate如何映射sqlserver中image字段
概述 有这样一个需求需要管理企业内网的信息,包括图标和链接.考虑到图标也不是很大所以就将图片直接保存在数据库中了. 但是用到Nhibernate,如何映射呢? Table 5.5. Large Obj ...
- NHibernate系列文章六:NHibernate数据类型映射
摘要 NHibernate支持所有的数据库数据类型. 以SQL Server数据库为例,下表是NHibernate支持的SQL Server数据库最常见的数据类型对照表. 第一列是NHibernate ...
- Fluent NHibernate关系映射
1.好处:Fluent NHibernate让你不再需要去写NHibernate的标准映射文件(.hbm.xml), 方便了我们的代码重构,提供了代码的易读性,并精简了项目代码 实现: (1).首先我 ...
随机推荐
- Rand
我看了下网上,是这样的:rand()随机产生一个数(0-65535),加上%后,就是对其它数求余,求余产生的数取决于求余的数.比如,rand()%20;意思是利用rand()的返回值(一个0-6553 ...
- RequireJS学习笔记(转)
前言 进入移动前端是很不错的选择,这块也是我希望的道路,但是不熟悉啊... 现在项目用的是require+backbone,整个框架被封装了一次,今天看了代码搞不清楚,觉得应该先从源头抓起,所以再看看 ...
- [资料] Apache2 的 httpd.conf 经典中文翻译
[i=s] 本帖最后由 www.PHP888.com 于 2009-5-22 13:40 编辑 [/i] # 基于 NCSA 服务的配置文件. # #这是Apache服务器主要配置文件. #它包含服务 ...
- 转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】
文章来自于:http://blog.renren.com/share/246648717/8171467499 基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴 ...
- ionic ng-src 在网页显示,但是导出apk在android手机中运行不显示图片
解决方法参照: http://stackoverflow.com/questions/29896158/load-image-using-ng-src-in-android-ionic-aplicat ...
- 检测鼠标键盘多久没有活动(使用GetLastInputInfo API函数检测)
DELPHI代码 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Contro ...
- 【HDOJ】4972 A simple dynamic programming problem
水题. #include <cstdio> #include <cstring> #include <cstdlib> int abs(int x) { ? -x: ...
- javascript变量:全局?还是局部?这个得注意!
做项目就是一个学习的过程! 做为一个学习C3年多,从C程序员转前端的人来说,javascript中的许多规则是没办法或者说一时半会理解不了的. 今天就遇到了一个,大致就是这么个代码. var a ; ...
- Java---设计模块(单例的变形)(多例)
设计模式1--单例变形(多例) ★ 缓存在单例中的使用 缓存在编程中使用很频繁,有着非常重要的作用,它能够帮助程序实现以空间换取时间,通常被设计成整个应用程序所共享的一个空间,现要求实现一个用缓存存放 ...
- [LeetCode] 179. Largest Number 解题思路
Given a list of non negative integers, arrange them such that they form the largest number. For exam ...