NHibernate初学体验记

      NHibernate 是一个基于.Net 的针对关系型数据库的对象持久化类库。NHibernate 来源于优秀的基于Java的关系型持久化工具Hibernate。NHibernate持久化你的.Net 对象到关系型数据库,远胜于写SQL去从数据库存取对象。你的代码仅仅和对象关联,NHibernat 自动产生SQL语句,并确保对象提交到正确的表和字段中去。NHibernate极大地减少了数据层代码的编写,当然提高了开发的效率和质量。体验一下吧。(有关Hibernate的资料请参考文末)

测试环境:单机安装Win2003SP2 + SQL2000 + .NET2.0 + VS2005

一、下载安装NHibernate

下载地址:http://sourceforge.net/project/showfiles.php?group_id=73818

运行安装程序NHibernate-1.2.1.GA.msi,默认情况下“C:"Program Files"NHibernate”目录下。

二、准备数据库

1.在SQL Server2000下创建NHibernate数据库;

2.执行如下SQL语句创建数据表users:


use NHibernate

go

CREATE TABLE users (

 LogonID nvarchar(20) NOT NULL default '0',

 Name nvarchar(40) default NULL,

 Password nvarchar(20) default NULL,

 EmailAddress nvarchar(40) default NULL,

 LastLogon datetime default NULL,

 PRIMARY KEY (LogonID)

)

go

三、开发程序
1.在VS2005中新建类库项目NHibernate.Examples,同时选中“创建解决方案目录”复选框。
   
    2.在NHibernate.Examples类库项目创建类文件User.cs,内容如下。(注:一个User对象对应数据表users中的一条记录。)


using System;

namespace NHibernate.Examples.QuickStart

{

    public class User

    {

        private string id;

        private string userName;

        private string password;

        private string emailAddress;

        private DateTime lastLogon;

        public User()

        {

        }

        public string Id

        {

            get { return id; }

            set { id = value; }

        }

        public string UserName

        {

            get { return userName; }

            set { userName = value; }

        }

        public string Password

        {

            get { return password; }

            set { password = value; }

        }

        public string EmailAddress

        {

            get { return emailAddress; }

            set { emailAddress = value; }

        }

        public DateTime LastLogon

        {

            get { return lastLogon; }

            set { lastLogon = value; }

        }

    }

}

3.在NHibernate.Examples类库项目创建映射文件User.hbm.xml,并将文件的“生成操作”属性设置为“嵌入的资源”(如图),映射文件将成为装配件的一部分。
            


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="NHibernate.Examples.QuickStart.User, NHibernate.Examples" table="users" lazy="false">
          <id name="Id" column="LogonId" type="String" length="20">
              <generator class="assigned" />
          </id>
          <property name="UserName" column= "Name" type="String" length="40"/>
          <property name="Password" type="String" length="20"/>
          <property name="EmailAddress" type="String" length="40"/>
          <property name="LastLogon" type="DateTime"/>
    </class>

</hibernate-mapping>

让我们来看看User.hbm.xml文件中让我们感兴趣的某些行。第一个有趣的标签是class。这里我们将映射类型名称(类名和装配件)到我们数据库中的User表,这里和Hibernate有一点点的不同。你将不得不告诉NHibernate从何处提取对象。在这个例子里我们从装配件NHibernate.Examples装载类NHibernate.Examples.QuickStart.User 。NHibernate 遵循和.Net Framework同样的规则来加载类型。因此如果你在如何指定类型的方面有些混淆,请参看.Net Framework SDK。

让我们先跳过id标签,来讨论property标签。简要看一下,你将发现NHibernate所要做的工作。name属性的值正是我们.Net 类的属性,column属性值将是我们数据库里的字段。type属性是可选的(如果你不标明,NHibernate将利用反射进行最佳的推测)。

好了,让我们回到标签id, 你可以猜测到这个标签将是映射数据库表的主键,的确如此,id标签的组成和我们刚才看的property标签是相似的。我们映射属性到目标数据库的字段。

内嵌的generator 标签告诉NHibernate 如何生成主键(它将恰当的为你生成主键,不管你指定何种类型,但你必须告诉它)。在我们的例子里,我们设定为assigned,意味着我们对象将自己生成主键(毕竟User对象常常需要一个UserID)。如果你执意要NHiberante为你生成主键,你感兴趣于设定uuid.hex和uuid.string(从文档中获取更多信息)

提示:如果你仅仅是改变映射文件,你不能使用build 而应该Rebuild项目。Visual Studio.Net 不会重新编译有改变的映射文件。

4.新建一个Windows应用程序项目NHibernateQuickStart,并添入已有的解决方案。
   

5.在项目NHibernateQuickStart中添加对NHibernate.dll的引用(默认安装情况下在“C:"Program Files"NHibernate"bin"net-2.0"NHibernate.dll”)。
   

6.在项目NHibernateQuickStart中添加对NHibernate.Examples类库项目的引用:
   

7. 在项目NHibernateQuickStart中添加应用程序配置文件App.config,内容如下:(告诉NHibernate 去哪里连接数据库以及数据库的相关配置)


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

<configuration>

 <configSections>

    <section

      name="nhibernate"

      type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

    />

 </configSections>

 <nhibernate>

    <add key="hibernate.connection.provider"

      value="NHibernate.Connection.DriverConnectionProvider"

    />

    <add key="hibernate.dialect"

      value="NHibernate.Dialect.MsSql2000Dialect"

    />

    <add key="hibernate.connection.driver_class"

      value="NHibernate.Driver.SqlClientDriver"

    />

    <add key="hibernate.connection.connection_string"

      value="Server=localhost;initial catalog=nhibernate;Integrated Security=SSPI"

    />

 </nhibernate>

</configuration>

8.开始编写写入数据的代码。

(1)在项目NHibernateQuickStart中Form1窗体上添一个按钮button1,双击button1进入代码编辑界面,我们将在button1_Click事件中编写代码。

(2)在代码中添加using声明:


using NHibernate;

using NHibernate.Cfg;

using NHibernate.Examples.QuickStart;

(3)button1_Click事件代码如下:


private void button1_Click(object sender, EventArgs e)

        {

            Configuration cfg = new Configuration();

            cfg.AddAssembly("NHibernate.Examples");

            ISessionFactory factory = cfg.BuildSessionFactory();

            ISession session = factory.OpenSession();

            ITransaction transaction = session.BeginTransaction();

            User newUser = new User();

            newUser.Id = "joe_cool_test";

            newUser.UserName = "Joseph Cool";

            newUser.Password = "abc123";

            newUser.EmailAddress = "joe@cool.com";

            newUser.LastLogon = DateTime.Now;

            // Tell NHibernate that this object should be saved

            session.Save(newUser);

            // commit all of the changes to the DB and close the ISession

            transaction.Commit();

            session.Close();

        }

(4)编译整个解决方案。执行生成的EXE文件NHibernateQuickStart.exe,点击button1。之后,打开数据库users表,如果产生了一条记录,则成功!

本项目源码下载:NHibernateQuickStart1.rar

    ===================================================================================

另外,本人还写了一个复杂点的示例,包含了增加、修改、删除、显示记录的操作:
    源码下载:NHibernateQuickStart2.rar。看了这个代码你会发现项目中充斥了如下类似的代码:


            Configuration cfg = new Configuration();

            cfg.AddAssembly("NHibernate.Examples");

            ISessionFactory factory = cfg.BuildSessionFactory();

            ISession session = factory.OpenSession();

            ITransaction transaction = session.BeginTransaction();

如何解决这个问题呢?以后再探讨吧J

===================================================================================

推荐阅读《Hibernate Quickly中文版》一书,虽然是针对Java的,但是思想是相通的,NHibernate本源于Hibernate,看了之后会Hibernate有全面深入的认识。

其它资料:

Hibernate官方网站:http://www.hibernate.org

NHibernate论坛:http://www.okec.cn

renrenqq的blog(有丰富的ORM资料):http://www.cnblogs.com/renrenqq

    (注:本人参考NHibernate官方快速指南未能测试成功,后整理本篇文档,参考了译文:http://www.okec.cn/htm_data/7/0709/194.html

=====================================================================================================
参考NHibernate官方快速指南编写代码遇到的问题:
From:http://hi.baidu.com/zsea/blog/item/7d999e3d8a54c203baa1678d.html

一、Test.Model.Person.hbm.xml(2,2): XML validation error: 未能找到元素“urn:nhibernate-mapping-2.0:hibernate-mapping”的架构信息。

       将2.0改为2.2

二、 The following types may not be used as proxies:
         Test.Model.Person: method set_Id should be virtual
         Test.Model.Person: method get_Name should be virtual
         Test.Model.Person: method set_Name should be virtual
         Test.Model.Person: method get_Id should be virtual

         类配置文件中Class的Lazy改为false
         网上搜到的三种解决方案:
        1.   You can follow the advice of the exception and add "virtual" to all of your properties, and make sure your class is non-sealed. Obviously you'll want to do this if you think you might want to take advantage of the lazy-initializing proxy feature.   However, changing your classes may not be practical or advisable if you have a legacy codebase, or it may just bother you that a "transparent" persistence framework is dictating how you design certain aspects of your value classes.   That's where Options 2 and 3 come in.   Both of those involve changing back to the old behavior.

          2.  To change the lazy-initialization proxy setting for a specific class, you can add a "lazy='false'" attribute to the <class> mapping element.   This might look something like:

<class
     name="NorthwindClasses.Category, NorthwindClasses"
     table="Categories"
     lazy="false"
>

        3.  To change the lazy-initialization proxy setting for all classes in a given mapping file, you can add a "default-lazy='false'" attribute to the <hibernate-mapping> element, as follows:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" default-lazy="false">

Unfortunately, Option 3 doesn't really help you much if you do one <class> mapping per <hibernate-mapping> file, a practice which I personally follow and recommend.   It's too bad, but there doesn't seem to be any way to set this default in the <nhibernate> global configuration.   But if you do happen to have all of your <class>'s in one .hbm.xml file, "default-lazy" can help you out.

时间: 2024-09-20 15:23:16

NHibernate初学体验记的相关文章

Tomcat的初学体验

初学 自已另建文件夹存放JSP文件时,一定要有下面几步: 一 在新建的文件夹(比如myjsp)下新建一个文件夹WEB-INF,注意目录名区分大小写. 二 在WEB-INF下新建一个文件web.xml,内容如下 <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application

QQ电脑管家6.1 Beta体验记

  界面又变脸 安装过程不想多说,毕竟大多数网友已经非常熟悉了,但接下来的界面绝对能让人拍案称绝.在QQ电脑管家6.1中,你会发现整个界面被重新进行了改动.原本使用率不高的"实时防护"."硬件检测"被同时撤下,并入到顶端栏的"工具箱"中."手机管理"(不是"手机软件频道"哟!)是新加入的一项功能,能够与你的Android手机.IPhone手机互通互信.同时在这一版中,图标的风格也看上去更加亲切可人. 图1

高端大气上档次的Uber体验记

前言:融资3.6亿美元后,Uber已成全球互联网焦点产品,最近我就在上海体验了下Uber,体会感只有一个:真是高端大气上档次啊!Uber竟然直接为笔者Call来一辆奔驰S350......文/氩媒体(微信号:Argonmedia)上海,是目前Uber在华唯一提供服务的城市,在某公司无聊的发布会期间,我下载了Uber软件.虽然从其官网的调性上,我已经知道Uber在华瞄准的是高端用车市场,Call来的都是奔驰宝马,属于"屌丝切勿靠近,否则后果自负"的类型,但抱着今生唯此一次的决心,我毅然打

《泡泡战士》国服体验记Q版风水枪玩法新颖

,作为NEXON旗下顶级工作室Lodumani开发的是一款第3人称射击网络游戏,<泡泡堂>和<跑跑卡丁车>的角色这次开始了水枪大战.<泡泡战士>国服测试已经进行了两轮测试,可爱的Q版风格与酣畅淋漓的水枪大作战给玩家们带来不少惊喜.小编有幸在封测中体验了一次这款游戏,下面就为大家带来<泡泡战士>的封测体验. 体会之一:地图多元,玩法多样 <泡泡战士>国服封测仅开放了皮蛋和黑妞两个角色,两次测试一共提供了六张地图,分别是:森林小乐园.森林遗忘山涧.泡

淘金网赚论坛:Discuz!联盟使用体验记

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 近来,论坛开通了Discuz!云平台服务,并采用了Discuz!联盟,且投放了近一个星期了.鉴于此,想写篇心得和大家分享分享.但是,由于论坛初建,流量不是很大,数据采集存在局限性,仅供大家参考.虽说,有投放Discuz!联盟,但是我仅在论坛顶部放置了个960x90全局顶部广告,这也是我个人的美观癖在作怪.早期,多个站点都没采用百度联盟.goo

DNF开发商新作《Cyphers》体验记虚幻3打造

(编译/小熙)由<DNF>研发公司Neople历经2年6个月研发的3D新作<窃密风云>(Cyphers,暂译)于日前开启了首测封测.小编有幸,参与了这款网游的一测,虽然作为虚幻3打造的全新3D游戏,但是游戏中有很多地方与Neople成名作<DNF>的些许相似. 虽然官方强调<Cyphers>的研发理念不同于<DNF>,但是我们依然能在这款动作AOS游戏身上发现了一些<DNF>的影子,比如奖励系统.比如人物的设计风格等等.(AOS游戏是

谷歌眼镜体验记:我成“眼镜混蛋”

自谷歌眼镜发布以来,褒奖与争议一直存在.日前,美国<连线>杂志记者Mat Honan于12月30日撰文,记录了他使用谷歌眼镜一年以来的使用感受,并预测了谷歌眼镜未来的发展趋势.以下是原文摘要: 我曾经想在第二个孩子出生时戴着谷歌眼镜,但我的妻子完全不能接受,她甚至感到很生气. 但当这一天慢慢到来,她开始喜欢它,并对它产生了兴趣. 我相信我的计划将受到欢迎.因为在这种情况下,谷歌眼镜有很多非常实用的地方:免提网络.语音识别,以及带有自动拍照功能的摄像头.碰碰太阳穴,你就能照相.长按那个按钮,你就

《星辰变》封测体验记玩到10级才可选定职业

(综合/小鸢) <星辰变>修行封测开始第3天,小编简单的体验了一番,来同大家一起分享小编初入星辰变对游戏各项系统的体会和心得. 一.职业选择:先玩游戏再选职业 玩家刚刚进入游戏时不用选择职业,只有一些角色的基本情况定义选择,玩家要到10级才会选定职业,小编认为这样的设定非常可行,可以有充足的时间让玩家熟悉游戏环境,从而选择自己喜欢的职业. 二.剧情动画:用剧情来进行新手引导 新建角色成功之后,会有长达10多分钟的剧情动画,一方面加强了玩家的代入感,再现<星辰变>小说中的经典剧情,以

《TERA》三大职业野外单人试玩视频与体验记

本网(编译/东方异国)在此次视频中将会看到3测中没有公开过的 左测大陆 45级野外"暴君高原"全景 和 目前在开发中的 "恶灵古城"入口. 开发人员对于3测中所提议的 针对低级玩家乱PK行为 决定了出生地区和 右侧大陆将限制随地PK, 但包括暴君高原的左侧大陆大多级别高的区域都将开放PK. [论坛原帖]TERA枪骑,狂战,剑斗士野外单人试玩体验笔记 ▲进入新区域试玩的枪骑士. ▲位于"暴君高原"的维斯托尼亚交界区包括在内的TERA世界左侧大陆大部