NHibernate从入门到精通系列

更新时间:2023-04-20 14:18:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

一、NHibernate概括

内容摘要

NHibernate简介

ORM简介

NHibernate优缺点

一、NHibernate简介

什么是?NHibernate?NHibernate是一个面向.NET环境的对象/关系数据库映射工具。对象/关系数据库映射(object /relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型数据结构中去。

在今日的企业环境中,把面向对象的软件和关系数据库一起使用可能是相当麻烦和浪费时间的。而NHibernate不仅仅管理.NET类到数据库表的映射(包括.NET 数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和961837205901020207409cd8处理数据的时间。

NHibernate的目标主要是用于与数据持久化相关的编程任务,能够使开发人员从原来枯燥的SQL语句的编写中解放出来,解放出来的精力可以让开发人员投入到业务逻辑的实现上。对于以数据为中心的程序,开发人员往往是在数据库中使用存储过程来实现商业逻辑,这种情况下NHibernate可能不是最好的解决方案,但对于那些基于.NET,并且能够实现OO业务模型和商业逻辑的中间层应用,NHibernate是最有用的。 NHibernate可以帮助用户消除或者包装那些针对特定厂商的SQL代码,并且帮用户把结果集从表格式的表示形式转换成一系列的对象。

NHibernate是一个目前应用的最广泛的开放源代码的对象关系映射框架,它对Java的JDBC(类似于961837205901020207409cd8)进行了非常轻量级的对象封装,使得程序员可以随心所欲的使用对象编程思维来操纵数据库,目前在国内Java开发界已经颇为流行,Hibernate+Spring往往是很多Java公司招聘的要求。而NHibernate,顾名思义,如同NUnit,NAnt一样,是基于.Net的Hibernate实现,但是目前介绍 NHibernate的资料非常少,缺少一个系统完整的教程来全面的展现和深入NHibernate,而且现在NHibernate的文档又残缺不全,少的可怜,很多NHibernate的学习者往往都是通过Hibernate的文档来学习,但是毕竟不是所有的.Net开发者都熟悉Java,也不是所有的人都有精力有时间去学习Java,所以,我准备开始一个Step by Step的NHibernate教程,以便有兴趣的朋友能够快速的熟悉NHibernate,能够更快地体验NHibernate的开发乐趣。

NHibernate 是一个基于.Net 的针对关系型数据库的对象持久化类库。NHibernate 来源于非常优秀的基于Java的Hibernate 关系型持久化工具。

NHibernate 从数据库底层来持久化你的.Net 对象到关系型数据库。NHibernate 为你处理这些,远胜于你不得不写SQL去从数据库存取对象。你的代码仅仅和对象关联,NHibernat 自动产生SQL语句,并确保对象提交到正确的表和字段中去。

二、ORM简介

什么是ORM?对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。

让我们从O/R开始。字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。

如果打开你最近的程序(如,PetShop4.0),看看DAL(数据库访问层)代码,你肯定会看到很多近似的通用的模式。我们以保存对象的方法为例,你传入一个对象,为SqlCommand对象添加SqlParameter,把所有属性和对象对应,设置

SqlCommand的 CommandText属性为存储过程,然后运行SqlCommand。对于每个对象都要重复的写这些代码。除此之外,还有更好的办法吗?有,引入一个 O/R Mapping。实质上,一个O/R Mapping会为你生成DAL。与其自己写DAL代码,不如用O/R Mapping。你用O/R Mapping保存,删除,读取对象,O/R Mapping 负责生成SQL,你只需要关心对象就好。

三、NHiberante的优缺点

3.1 优点

(1).面向对象:NHiberante的使用时只需要操纵对象,使开发更对象化,抛弃了数据库中心的思想,完全的面向对象思想。

(2).透明持久化:带有持久化状态的、具有业务功能的单线程对象,此对象生存期很短。这些对象可能是普通的POCO,这个对象没有实现第三方框架或者接口,唯一特殊的是他们正与(仅仅一个)Session相关联。一旦这个Session 被关闭,这些对象就会脱离持久化状态,这样就可被应用程序的任何层自由使用。(例如,用作跟表示层打交道的数据传输对象。)

(3).它没有侵入性,即所谓的轻量级框架。正因为它具有透明持久化的优点,它才没有侵入性,才是一个轻量级框架。恒定一个框架为重量级、还是轻量级,是根据其侵入性而定夺的。而NHibernate就是一个轻量级ORM框架。

(4).较好的移植性:支持多种数据库,便于数据库的迁移。

(5).缓存机制:提供一、二级缓存和查询缓存。

(6).开发效率:众所周知,使用NHibernate可以简化程序开发,从而达到快速开发的目的。作为软件公司,项目管理的关键就是控制开发成本。正因为使用NHibernate后所写的代码量减少了,相对于原先使用“SqlHelper、DAL、BLL”开发程序的项目周期缩短了,成本就降低了。

3.2 缺点

(1).内存消耗:直接使用“SqlHelper、DAL、BLL”无疑是最省内存的。使用NHibernate后,内存开销比较大,这点是毋庸置疑的。

(2).批量数据库的处理:由于NHibernate是基于面向对象的ORM框架,处理数据库的方式是针对单个对象的。对数据库的增、删、改都是正对一条记录而言。对于批量修改、删除数据,不适合用NHiberante。这也是所有OR框架弱点,其原因,我认为是在于与缓存机制的冲突。

(3).较多使用数据库特性时,也不适合使用NHiberante。如数据库中大量的存储过程、触发器、特点的SQL语句。

(4).表关系比较混乱时也不适合使用NHiberante。NHibernate只适合于表与表的关系比较明确的环境中。如本应该建立外键的,没有建立外键。这时使用NHiberante不仅没有减少工作量,反而增加了工作量。

(5).学习成本:相对于NHibernate来说,使用“SqlHelper、DAL、BLL”操作数据库,学习成本比较低,而且上手很快。使用NHibernate需要有一定OOP(面向对象编程)和OOD(面向对象设计)的基础,这对于基础薄弱的程序员来说,从面向过程的编程到面向对象的编程,需要一定的投入;一般情况下需要学习1个月左右的时间才能够深入NHiberante。

二、NHibernate环境与结构体系

内容摘要

NHibernate的开发环境

NHibernate的结构体系

NHibernate的配置

一、NHibernate的开发环境

NHibernate的英文官方网站为:961837205901020207409cd8/

NHibernate目前最新的版本是3.0.0.GA,其下载地址是:

961837205901020207409cd8/projects/nhibernate/files/NHibernate/

我可以下载NHibernate-3.0.0.GA-bin.zip(编译后的dll),也可以下

载 NHibernate-3.0.0.GA-src.zip(源文件),另外再下载

NHCH-3.0.0.GA-bin.zip(NHibernate二级缓存库)。

图1.1

下载并解压NHibernate-3.0.0.GA-bin.zip后,如图1.1所示。

?其中名为“Required_Bins”的文件夹所放置的是NHiberante主程序的dll程序集。

(1).Antlr3.Runtime.dll为:Antlr的程序集。Antlr(ANother Tool for Language Recognition)是一个工具,它为我们构造自己的识别器(recognizers)、编译器(compiler)和转换器(translators)提供了一个基础。通过定义自己的语言规则,Antlr可以为我们生成相应的语言解析器,这样便可以省却了自己全手工打造的劳苦。

(2).Iesi.Collections.dll为:NHibernate程序的集合库,因为

在.NET4.0之前,没有提供ISet这样的集合,所以NHiberante框架的设计者们就将ISet这样的集合放置在这个程序集里。我建议NHiberante框架的设计人员,在.NET4.0以后的程序,使用System.Collections.Generic.ISet这个接口。

(3).NHibernate.dll为主程序集

(4).Remotion.Data.Linq.dll为:NHibernate to Linq的类库。

(5).nhibernate-configuration.xsd和nhibernate-mapping.xsd分别为 NHibernate程序配置和映射配置的xsd文件,我们把这个两个文件复制到Microsoft Visual Studio安装目录的\Xml\Schemas下,就会有xml的自动提示功能。

?名为“Required_For_LazyLoading”的文件夹所放置的是NHiberante延迟加载代理用到的程序集,其中提供了Castle、LinFu、Spring这三种代理类。我选择其中一项就可以了。

?名为“Configuration_Templates”的文件夹所放置的是NHiberante的配置模板。已给出了FireBird、MSSQL、MySql、Oracle、PostgreSQL、

SQLite的配置模板。

二、NHiberante的结构体系(Architecture)

图2.1

从图2.1可以看出,NHibernate使用数据库和配置信息来为应用程序提供持久化服务(以及持久的对象)。

我们来更详细地看一下NHibernate运行时体系结构。由于NHibernate非常灵活,且支持多种应用方案,所以我们这只描述一下两种极端的情况。“轻型”的体系结构方案,要求应用程序提供自己的961837205901020207409cd8 连接并管理自己的事务。这种方案使用了NHibernate API的最小子集:

图2.2

“全面解决”的体系结构方案,将应用层从底层的961837205901020207409cd8 API中抽象出来,而让NHibernate来处理这些细节。

图2.3

图2.3中各个对象的定义如下:

ISessionFactory (NHibernate.ISessionFactory)

针对单个数据库映射关系经过编译后的内存镜像,是线程安全的(不可

变)。它是生成ISession的工厂,本身要用到IConnectionProvider。

该对象可以在进程或集群的级别上,为那些事务之间可以重用的数据提供可选的二级缓存。

ISession (NHibernate.ISession)

表示应用程序与持久储存层之间交互操作的一个单线程对象,此对象生存期很短。其隐藏了961837205901020207409cd8连接,也是ITransaction的工厂。其会持有一个针对持久化对象的必选(第一级)缓存,在遍历对象图或者根据持久化标识查找对象时会用到。

持久的对象及其集合(Persistent Objects and Collections)

带有持久化状态的、具有业务功能的单线程对象,此对象生存期很短。这些对象可能是普通的POCOs,唯一特殊的是他们正与(仅仅一个)

ISession相关联。一旦这个ISession被关闭,这些对象就会脱离持久化状态,这样就可被应用程序的任何层自由使用。(例如,用作跟表示层打交道的数据传输对象。)

瞬态(transient)和脱管(detached)的对象及其集合

那些目前没有与ISession关联的持久化类实例。他们可能是在被应用程序实例化后,尚未进行持久化的对象。也可能是因为实例化他们的

ISession已经被关闭而脱离持久化的对象。

ITransaction (NHibernate.ITransaction)

(可选的)应用程序用来指定原子操作单元范围的对象,它是单线程的,生命周期很短。它通过抽象将应用从底层具体的961837205901020207409cd8事务隔离开。

某些情况下,一个ISession之内可能包含多个ITransaction对象。

IConnectionProvider (NHibernate.Connection.IConnectionProvider)

(可选的)生成961837205901020207409cd8连接以及Command对象的工厂。它通过抽象将应用从底层的IDbConnection或IDbCommand隔离开。仅供开发者扩展/实现用,并不暴露给应用程序使用。

IDriver (NHibernate.Driver.IDriver)

(可选的)一个封装了不同961837205901020207409cd8 providers之间的差异(利用参数命名转换等961837205901020207409cd8支持的特性)的接口。

ITransactionFactory (NHibernate.Transaction.ITransactionFactory)

(可选的)生成ITransaction对象实例的工厂。仅供开发者扩展/实现用,并不暴露给应用程序使用。

三、NHibernate的配置

由于NHibernate是为了能在各种不同环境下工作而设计的, 因此存在着大量的配置参数. 幸运的是多数配置参数都有比较直观的默认值。我打开MSSQL.cfg文件,如图所示,可以观察到NHibernate的配置。

图3.1

3.1 NHibernate提供961837205901020207409cd8连接配置

3.2 可选的配置属性

有大量属性能用来控制NHibernate在运行期的行为. 它们都是可选的, 并拥有适当的默认值。

三、第一个NHibernate应用程序

内容摘要

准备工作

开发流程

程序开发

一、准备工作

1.1开发环境

开发工具:VS2008以上,我使用的是VS2010

数据库:任意关系型数据库,我使用的是SQL Server 2005 Express

1.2测试环境

nunit 2.5.7

二、开发流程

NHibernate程序的开发流程是:

(1).编写领域类与映射文件

(2).使用NHibernate工具生成对应的数据库结构

(3).编写DAO(数据库访问对象)

(4).使用NUnit测试DAO(数据访问对象)的增、删、该、查方法

三、程序开发

3.1 建立Domain项目,如图3.1.1所示。

图3.1.1

编写类文件Product.cs

Product

///

///商品

///

public class Product

{

///

/// ID

///

public virtual Guid ID { get; set; }

///

///编号

///

public virtual string Code { get; set; }

///

///名称

///

public virtual string Name { get; set; }

///

///规格

///

public virtual string QuantityPerUnit { 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; }

}

编写映射文件Product.hbm.xml

Product.hbm.xml

然后,将映射文件“Product.hbm.xml”的属性“生成方式”设置为“嵌入的资源”,如图3.1.2所示。

图3.1.2

3.2 建立名为“NHibernateTest”的项目,如图3.2.1所示

图3.2.1

引用程序集“Antlr3.Runtime.dll”,“Iesi.Collections.dll”,“NHibernate.dll”,“Remotion.Data.Linq.dll”,

“nunit.framework.dll”,如图3.2.2所示

图3.2.2

然后音乐Domain项目,复制并粘贴NHibernate的配置模板到项目中,如图3.2.3所示

图3.2.3

修改该文件的属性为“始终复制”

hibernate.cfg.xml