`
ron
  • 浏览: 30591 次
  • 性别: 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 c#nhibernate c#nhibernate c#nhibernate c#nhibernate c#nhibernate c#nhibernate c#

    NHibernate-2.1.2.GA-bin NHibernate框架

    NHibernate 是一个强大的持久化框架,专为 .NET 开发设计,它简化了数据库与对象之间的交互,使得开发者可以更加关注业务逻辑而不是底层的数据访问细节。这个“NHibernate-2.1.2.GA-bin”压缩包包含了 NHibernate 的...

    NHibernate

    以下是关于NHibernate的一些关键知识点: 1. **对象关系映射(ORM)**:NHibernate实现了对象关系映射,将数据库表映射为.NET类,表中的记录映射为类的实例。这样,开发人员可以通过操作对象而非SQL来实现数据库...

    Fluent nHibernate

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

    Nhibernate_一步一步

    ### NHibernate:逐步详解 #### 一、O/R Mapping 概念及NHibernate简介 **O/R Mapping**,即对象关系映射(Object/Relational Mapping),是一种编程技术,用于将对象模型与关系型数据库之间建立映射关系。简单来说...

    NHibernate_Demo

    在这个Demo中,我们将深入探讨以下几个关键知识点: 1. **对象关系映射(ORM)基础**:ORM是将关系数据库中的数据模型转换为对象模型的技术,它允许开发者使用面向对象的方式来处理数据库操作,提高了代码的可读性...

    Nhibernate

    **Nhibernate** 是一个流行的开源对象关系映射(ORM)框架,它为.NET开发者提供了在各种数据库系统上操作...此外,还可以了解到如何处理事务和优化性能,这些都是使用Nhibernate开发高效、灵活的应用程序时的关键技能。

    NHibernate2.0中文文档

    在这个中文文档中,你可能会学到以下知识点: 1. **对象关系映射(ORM)基础**:了解ORM如何将数据库表映射到对象,以及对象间的关联如何对应到数据库的关系。 2. **NHibernate配置**:学习如何设置NHibernate的...

    NHibernate 3 3 Sample 例子

    **NHibernate 3.3 Sample 知识点详解** NHibernate 是一款强大的对象关系映射(ORM)框架,用于.NET 应用程序。它允许开发人员将.NET 类映射到数据库表,从而减少了与数据库交互时的手动SQL 编写工作。在本示例中,...

    NHibernate+Oracle NHibernate+MySql Demo

    NHibernate 是一个强大的对象关系映射(ORM)框架,它允许开发者在.NET环境中使用SQL数据库,如Oracle和MySQL,而不必直接编写SQL语句。这个"NHibernate+Oracle NHibernate+MySql Demo"是一个示例项目,展示了如何...

    NHibernate 3.0 源代码

    - 理解NHibernate的扩展点,以便自定义行为或添加新的功能。 - 发现性能优化技巧,通过源码分析找出可能的瓶颈并进行改进。 - 探索事务管理和并发控制的实现,这对于开发高并发的应用至关重要。 - 熟悉单元测试和...

    Nhibernate 2.0.1.GA

    4. **会话工厂**:它是Nhibernate的主要入口点,负责创建会话实例,管理数据库连接。 5. **会话**:会话是数据库操作的工作单元,它封装了数据库事务,并负责对象的加载、保存、更新和删除。 6. **查询API**:...

    学习经典NHibernate框架

    NHibernate是一款强大的对象关系映射(ORM)框架,它在.NET环境中广泛应用于数据库访问层,极大地简化了数据操作。此框架允许开发人员使用面向对象的方式来处理数据库操作,从而避免了手动编写大量的SQL语句,提高了...

    学习NHibernate的范例

    在NHibernate中,我们有以下关键组件: 1. **配置**:NHibernate的配置文件(通常为hibernate.cfg.xml)包含了数据库连接信息、方言、缓存策略等设置。开发者需要在此处指定数据库驱动、URL、用户名和密码。 2. **...

    nhibernate教程

    ### NHibernate教程知识点详解 #### 一、NHibernate简介与概念理解 NHibernate是一个强大的对象关系映射(Object-Relational ...通过掌握上述关键知识点,开发者可以更高效地利用NHibernate来构建高质量的应用程序。

    NHibernate引用的类库

    下面我们将深入探讨NHibernate的一些关键知识点: 1. **对象关系映射(ORM)**:ORM是一种编程技术,用于将数据存储在关系数据库中,同时保持面向对象的编程风格。NHibernate作为ORM工具,使得数据库操作变得更加...

    NHibernate.JetDriver(基于NHibernate 3.1)

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

Global site tag (gtag.js) - Google Analytics