`
ron
  • 浏览: 30026 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

NHibernate的关键点精要

阅读更多

        学习NHibernate,使用NHibernate总是有太多的疑惑。原来以后不就是个配置文件,后来才发现远远没有那么简单,这个配置文件又要照顾Entity Class,又要照顾数据库脚本生成,更要照顾动态的SQL语句生成,所以现在想来碰到这么多问题也是正常了。这些问题,有些在同事间、或者自己琢磨已经有结果,但是有很多问题是直到看了孙姐姐的书《精通HIBERNATE:Java对象持久化技术详解》,才豁然开朗。NHibernate组织自己也说,现在离1.0的最终发布版本差的就是文档了,所以NHibernate文档的缺乏更加加深了掌握的难度,但是幸好它是Hibernate的一个port,所以学习NHibernate最好的资料就是Hibernate的各种介绍和书籍了。下面就讲我认为比较重要的一一列出了。

1、持久层开发的最佳路线图:hbm->entity class->database scripts
hbm是信息最丰富的,所以由它作为驱动因素是最理想的,当然如果是项目的约束的影响那就另当别论了(比如数据库已经设计好了)。从hbm->entity class可以使用NHibernateContrib库(NHibernate官方开发的),最后生成database scripts的功能NHibernate库已经自带了。写hbm实际上不困难,只有将NHibernate自带的几个xsd文件拷贝到VS相应目录下就可以使用智能提醒了,写起来可谓是运指如飞。另外有个叫Object Mapper的工具提供了从UML图自动生成hbm的功能,不过我试了一下不是很爽,没有直接写快。

2、要Lazy Load,还是要清晰的DAL Service层?
(N)Hibernate一再强调Lazy Load的重要性,所他如何可以增加程序的性能,但是经过一段时间的研究发现Lazy Load固然好,但是可能会破坏企业应用架构。首先Lazy Load的使用有一个前提就是必须在同一个Session中,否则NHibernate给Lazy Load的类加的动态代理的事前拦截将无法捕获合适的Session因此在后来读Lazy Load的属性时会去用已经关闭的Session,自然就会throw exception了。另外,按照依赖颠倒的原则,一般我们都这样来BLL层下的架构“BLL ----> IDAL <--- DALImpl”,那么在DAL的每个方法中,必须经历Session打开和关闭的过程,因此当BLL层获得某个持久类,实际上是游离状态的,即Session已经关闭,此时BLL层在去读设置了Lazy Load的属性,就注定失败了。那么如何才能应用Lazy Load?一个办法在BLL中用NHiberante的Session等,但这样显然破坏了原本清晰的架构。所以我的理解是:Lazy Load和清晰的DAL Service层,二者不可兼得。当然最好是我理解错了,:)

3、inverse属性
该属性通常存在于双向管理关系中的<set>等列表标签中,其含义是“是否是镜像”的含义。比如在many-to-one双向关联关系中One方的<set>标签中若设置了inverse=true,则表示One方的关系设定只是一个镜像,而该关系的最终生成SQL则完全用Many方决定。因此当运行一下脚本:







1One theOne = new One();
2Many theMany = one Many();
3
4// 此处省略常规属性的赋值
5
6theOne.TheMany = theMany;
7theMany.OneList.Add(theOne);
数据库只会生成一条插入到TableMany中INSERT语句。
如果将One方<set>标签中的inverse属性改成false,则就会生成2条SQL语句,一条是插入到TableMany表中,第二条是UPDATE TableMany表中的外键使得其指向TableOne中的theOne记录。其实道理也很简单,如果“是否是镜像”为否,则由One方自己控制,它能控制的方法就是UPDATE TableMany表了,所以就2条SQL语句了。由此也可以推出若One方的<set>标签中若设置了inverse=true,代码片断中的第7行也可以不需要了。

4、实体类间组合关系
组合关系在UML中用实心的菱形表示,意思是同生共死。那么在NHibernate中就应该在父方加上cascade="all-delete-orphan"如下代码所示:
1<set 
2    name="orders" 
3    cascade="all-delete-orphan" 
4    inverse=true>
5    <key column="CustomerId" />
6    <one-to-many class="Order" />
7</set>

这样设置后NHibernate会帮助完成以下3件事情:
1、级联保存或更新,相当于cascade属性设置了"save-update"的情况。
2、级联删除,相当于cascade属性设置了"delete"的情况。
3、删除没有父的所有子对象。

5、类图中是2个类,但存储使用一个表
这种情况很多,比如一个系统中有用户和地址,在类图中应该是2个类会比较清晰,但是有时确希望在数据库中存放在1个表中,这时候可以用<component />标记,如下所示:






 1<class name="User">
 2    <id name="Id">
 3        <generator class="native"/>
 4    </id>
 5    <property name="FirstName"/>
 6    <property name="LastName"/>
 7    <component name="Component" class="UserSettings">
 8        <property name="Address1"/>
 9        <property name="Address2"/>
10        <property name="Street"/>
11        <property name="State"/>
12        <property name="Country"/>
13    </component>
14</class>


6、继承关系的几种映射方法

继承关系的映射可以有3种方法:每个具体类映射一张表、全部映射成一张表、每个类映射一张表(包括抽象类),下面是实例,有一个基类:Animal,二个子类:Dog、Cat。

每个具体类映射一张表:

 1<class name="Dog">
 2    <id name="Id">
 3        <generator class="native"/>
 4    </id>
 5    <property name="Name"/>
 6</class>
 7
 8<class name="Cat">
 9    <id name="Id">
10        <generator class="native"/>
11    </id>
12    <property name="Name"/>
13</class>

这种方式实际上是没有继承,不能使用以下查询语句:

1List Animals = session.find("from Animal");


全部映射一张表:

 1<class name="Animal" >
 2    <id name="Id">
 3        <generator class="native"/>
 4    </id>
 5    <discriminator column="Type" type="string" />
 6    <property name="Name"/>
 7
 8    <subclass name="Dog" discriminator-value="D">
 9    </subclass>
10
11    <subclass name="Cat" discriminator-value="C">
12    </subclass>
13
14</class>


每个类一个表(包括抽象类):

 1<class name="Animal" >
 2    <id name="Id">
 3        <generator class="native"/>
 4    </id>
 5    <discriminator column="Type" type="string" />
 6    <property name="Name"/>
 7
 8    <joined-subclass name="Dog">
 9        <key column="DogId" />
10    </joined-subclass>
11
12    <joined-subclass name="Cat">
13        <key column="CatId" />
14    </joined-subclass>
15</class>


7、如何告知hbm2DDL,我要生成ntext属性?
type="StringClob"是不管用得,应该是type="String" 然后设置一个大于4000的值给length,如length=5000,即可。



浅水滩 2005-08-16 00:07 发表评论





分享到:
评论

相关推荐

    nhibernate 源码nhibernate 源码

    nhibernate 源码nhibernate 源码nhibernate 源码nhibernate 源码

    nhibernate

    nhibernate c#nhibernate c#nhibernate c#nhibernate c#nhibernate c#nhibernate c#nhibernate c#

    Fluent nHibernate

    Fluent nHibernate,简化nHibernate工作量的好工具。 nHibernate相信用C#跟数据库打交道的多少知道一些,用过nHibernate的对其中nHibernate的XML配置文件的繁杂应该深有印象。Fluent nHibernate就是为简化nHibernate...

    NHibernate2.0中文文档

    NHibernate2.0中文文档 NHibernate2.0中文文档 NHibernate2.0中文文档

    NHibernate-2.1.2.GA-bin NHibernate框架

    使用与.net开发的NHibernate框架,这个版本是比较老,但是比较经典的。 我也是使用这个来在.net开发的。给大家共享一下。

    NHibernate.JetDriver(基于NHibernate 3.1)

    让NHibernate支持Access数据库的驱动程序,源自Hibernate官方,但官方早不支持了(已从NHibernate主类库剔除),这个是基于NHibernate 3.1.0.4000的,需要NHibernate其他版本的话,请打开解决方案引入不同版本的...

    NHibernate+Oracle NHibernate+MySql Demo

    实现NHibernate+Oracle 与NHibernate+MySql 的连接,以及增删改查的初步使用

    Nhibernate3.0

    最新的3.0版本,Welcome to NHibernate! -------------------------------------------------------------------------------- NHibernate is a .NET based object persistence library for relational databases....

    NHibernate

    NHibernate 初学者学习,,讲解详细,,高清pdf。不辣眼睛

    NHibernate Designer 2.0

    关键的新特性: 增加每个人生成单独文件的选项 创建新模型时的设置向导 支持内置 XML 或 Fluent NHibernate 生成映射 配置向导功能,更方便快速的集成到已有项目 Automatically add references to required ...

    Nhibernate从入门到精通

    NHibernate 入门之旅教程 PDF版,写这个小书也算是对自己学习NHibernate的一个总结吧。再次向对NHibernate陌生的朋友介绍一下NHibernate,它是一个面向.NET 环境的对象/关系数据库映射工具。用来把对象映射到基于SQL...

    NHibernate Inverse & Cascade

    NHibernate Inverse & Cascade

    Nhibernate_一步一步

    Nhibernate_一步一步

    NHibernate中文文档

    而NHibernate,顾名思义,如同NUnit,NAnt一样,是基于.Net的Hibernate实现,但是目前介绍NHibernate的资料非常少,缺少一个系统完整的教程来全面的展现和深入NHibernate,而且现在NHibernate的文档又残缺不全,少的...

    NHibernate 3 3 Sample 例子

    NHibernate 3.3 Sample

    nhibernate2.1.2帮助

    nhibernate2.1.2帮助手册nhibernate2.1.2帮助手册nhibernate2.1.2帮助手册nhibernate2.1.2帮助手册nhibernate2.1.2帮助手册nhibernate2.1.2帮助手册nhibernate2.1.2帮助手册

    学习NHibernate的范例

    学习NHibernate的范例!!

    NHibernate实例

    NHibernate小实例 增删改查NHibernate

    [ORM] NHibernate 3.3.3

    NHibernate is a port of Hibernate Core for Java to the .NET Framework. It handles persisting plain .NET objects to and from an underlying relational database. Given an XML description of your entities...

Global site tag (gtag.js) - Google Analytics