Nhibernate系列学习之(一) ORM and Nhibernate入门实例解析

       最近框架项目需要,数据层想使用Nhibernate,代替传统的sql语句的写法,更加使用面向对象的思维来维护实体与数据库的这层关系映射(ORM),好在之前接触过Java时学习使用了Hibernate,先来了解ORM。

    什么是ORM?

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

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



       Nhibernate是Hibernate在.NET环境中的实现。功能和目的上两者区别不大。在实现的机制方面,Nhibernate频繁地使用C#的新语法现象——lamda表达式,所以其使用方式看起来有点怪,没有Hibernate简明。


什么是?NHibernate?

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



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

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


与以前写代码的不同于提高

  如果打开你最近的程序(如,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,你只需要关心对象就好。




步骤一:建实体对象Product


<span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Domain
{
    /// <summary>
    /// 商品
    /// </summary>
    public class Product
    {
        /// <summary>
        /// ID
        /// </summary>
        ///
        public virtual Guid ID { get; set; }

        /// <summary>
        /// 编号
        /// </summary>
        public virtual string Code { get; set; }

        /// <summary>
        /// 名称
        /// </summary>
        public virtual string Name { get; set; }

        /// <summary>
        /// 规格
        /// </summary>
        public virtual string QuantityPerUnit { get; set; }

        /// <summary>
        /// 单位
        /// </summary>
        public virtual string Unit { get; set; }

        /// <summary>
        /// 售价
        /// </summary>
        public virtual decimal SellPrice { get; set; }

        /// <summary>
        /// 进价
        /// </summary>
        public virtual decimal BuyPrice { get; set; }

        /// <summary>
        /// 备注
        /// </summary>
        public virtual string Remark { get; set; }
    }
}
</span>

2、在Product对象的同一项目(同一目录)下新建一个与实体对象同名的XML文件,以“.hbm.xml”为扩展名。如:Product.hbm.xml
<span style="font-size:18px;"><?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" precision="14" scale="2"/>
    </property>

    <property name="BuyPrice" type="decimal">
      <column name="BuyPrice" precision="14" scale="2"/>
    </property>

    <property name="Remark" type="string">
      <column name="Remark" length="200"/>
    </property>

  </class>
</hibernate-mapping>
</span>

这里重点说一下 assembly 和 namespace属性。

assembly:集合的名称,如果在一个项目下有许多个实体对象,我们只需要指定这个属性,并在web.config中加入 如: “<mapping assembly="Domain"/>”就行了。
namespace:命名空间,如果设定了这个属性,class的 name只要指定与实体对象同名就行了。

还有要特别注意的是:XML文件的默认生成操作为“内容”,这里需要修改为“嵌入的资源”生成,因为NHibernate是通过查找程序集中的资源文件映射实体。这样在生成类库DLL文件时,这个XML文件才会打包进去,同时名称要自动修改为“Product.hbm.xml”。


3、web.config中进行配置


<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<!-- 
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it 
for your own use before compile tests in VisualStudio.
-->
<!-- This is the System.Data.dll provider for SQL Server -->
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
	<session-factory name="NHibernateTest">
		<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
		<property name="connection.connection_string">
      <!--数据库的用户名密码-->
      server=.;database=NHibernateDemo;uid=sa;pwd=123456;
    </property>
		<property name="adonet.batch_size">10</property>
    <!--是否显示sql语句-->
		<property name="show_sql">true</property>
    
    <!--数据库的方言-->
		<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
		<property name="use_outer_join">true</property>
		<property name="command_timeout">60</property>
    <!--数据库操作的方式-->
    <property name="hbm2ddl.auto">update</property>
		<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
		<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
    <!--找到对应的实体对象-->
    <mapping assembly="Domain"/>
	</session-factory>
</hibernate-configuration></span>

4、新建IProductDao操作类


<span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain;

namespace Dao
{
    public interface IProductDao
    {
        object Save(Product entity);

        void Update(Product entity);

        void Delete(Product entity);

        Product Get(object id);

        Product Load(object id);

        IList<Product> LoadAll();
    }
}
</span>


5、 ProductDao
<span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NHibernate;
using NHibernate.Linq;

namespace Dao
{
    public class ProductDao : IProductDao
    {
        private ISessionFactory sessionFactory;



            // 默认从 App.config,web.config或者hibernate.cfg.xml查找配置文件;
            //var cfg = new NHibernate.Cfg.Configuration().Configure();
 
             如果配置文件不是以上“App.config,web.config或者hibernate.cfg.xml”,是自定义的配置文件名称;
             要注意使用MSTest进行单元测试时,请写配置文件的绝对路径,否则找不到;
            var cfg = new NHibernate.Cfg.Configuration().Configure("D:/ProjectStudyTest/NHibernate/NHibernateStudy/Lesson3.Dao/Config/hibernate.cfg.xml");
 
            如果用户Nunit进行单元测试,写相对路径即可。
            var cfg = new NHibernate.Cfg.Configuration().Configure("Config/hibernate.cfg.xml");
 
            //sessionFactory = cfg.BuildSessionFactory();
        public ProductDao()
        {
            //加载
            var cfg = new NHibernate.Cfg.Configuration().Configure("Config/hibernate.cfg.xml");
            sessionFactory = cfg.BuildSessionFactory();
        }

        public object Save(Domain.Product entity)
        {
            using (ISession session = sessionFactory.OpenSession())
            {
                var id = session.Save(entity);
                session.Flush();
                return id;
            }
        }

        public void Update(Domain.Product entity)
        {
            using (ISession session = sessionFactory.OpenSession())
            {
                session.Update(entity);
                session.Flush();
            }
        }

        public void Delete(Domain.Product entity)
        {
            using (ISession session = sessionFactory.OpenSession())
            {
                session.Delete(entity);
                session.Flush();
            }
        }

        public Domain.Product Get(object id)
        {
            using (ISession session = sessionFactory.OpenSession())
            {
                return session.Get<Domain.Product>(id);
            }
        }

        public Domain.Product Load(object id)
        {
            using (ISession session = sessionFactory.OpenSession())
            {
                return session.Load<Domain.Product>(id);
            }
        }

        public IList<Domain.Product> LoadAll()
        {
            using (ISession session = sessionFactory.OpenSession())
            {
                return session.Query<Domain.Product>().ToList();
            }
        }
    }
}
</span>


7、ProductDaoTest测试类


<span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NUnit.Framework;
using Dao;

namespace NHibernateTest
{
    [TestFixture]
    public class ProductDaoTest
    {
        private IProductDao productDao;

        [SetUp]
        public void Init()
        {
            productDao = new ProductDao();
        }

        [Test]
        public void SaveTest()
        {
            var product = new Domain.Product
            {
                ID = Guid.NewGuid(),
                BuyPrice = 10M,
                Code = "ABC123",
                Name = "电脑",
                QuantityPerUnit = "20x1",
                SellPrice = 11M,
                Unit = "台"
            };

            var obj = this.productDao.Save(product);

            Assert.NotNull(obj);
        }

        [Test]
        public void UpdateTest()
        {
            var product = this.productDao.LoadAll().FirstOrDefault();
            Assert.NotNull(product);

            product.SellPrice = 12M;

            Assert.AreEqual(12M, product.SellPrice);
        }

        [Test]
        public void DeleteTest()
        {
            var product = this.productDao.LoadAll().FirstOrDefault();
            Assert.NotNull(product);

            var id = product.ID;
            this.productDao.Delete(product);
            Assert.Null(this.productDao.Get(id));
        }

        [Test]
        public void GetTest()
        {
            var product = this.productDao.LoadAll().FirstOrDefault();
            Assert.NotNull(product);

            var id = product.ID;
            Assert.NotNull(this.productDao.Get(id));
        }

        [Test]
        public void LoadTest()
        {
            var product = this.productDao.LoadAll().FirstOrDefault();
            Assert.NotNull(product);

            var id = product.ID;
            Assert.NotNull(this.productDao.Get(id));
        }

        [Test]
        public void LoadAllTest()
        {
            var count = this.productDao.LoadAll().Count;
            Assert.True(count > 0);
        }
    }
}
</span>

到此开始使用NUnit进行的单元测试






数据库中的如下,已经帮我们自动创建完成:





优点

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

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

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

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

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

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



以后NET开发模式,我们更应该尝试使用面向对象思维开发,这样来说,后期的维护成本大大的降低


(接下来会利用业余时间使用Net的一套搭建Nsprint+NHibernate+Nstructs+WCF+Windows+Silverlight+等中小型企业级系统开发平台)。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 28
    评论
NHibernate 之旅(1):开篇有益.............................................................................................5 NHibernate 开篇有益 ................................................................................................5 NHibernate 是什么 ....................................................................................................5 NHibernate 的架构 ....................................................................................................6 NHibernate 资源 ........................................................................................................7 欢迎加入 NHibernate 中文社区 ...............................................................................7 NHibernate 之旅(2):第一个 NHibernate 程序..............................................................8 开始使用 NHibernate ................................................................................................8 1.获取 NHibernate ....................................................................................................9 2.建立数据库表 ..............................................................................................................9 3.创建 C#类库项目 .....................................................................................................10 4.编写 DomainModel 层 ........................................................................................11 5.编写数据访问层 ........................................................................................................13 6.编写数据访问层的测试 ............................................................................................15 结语.................................................................................................................................17 NHibernate 之旅(3):探索查询之 NHibernate 查询语言(HQL)..............................17 NHibernate 中的查询方法 ......................................................................................18 NHibernate 查询语言(HQL).................................................................................18 实例分析.........................................................................................................................22 结语.................................................................................................................................23 NHibernate 之旅(4):探索查询之条件查询(Criteria Query) ...................................24 NHibernate 中的查询方法 ......................................................................................24 条件查询(Criteria Query).....................................................................................24 根据示例查询(Query By Example) ...................................................................26 实例分析.........................................................................................................................27 结语.................................................................................................................................28 NHibernate 之旅(5):探索 Insert, Update, Delete 操作 .......................................28 操作数据概述.................................................................................................................28 1.新建对象 ....................................................................................................................29 2.删除对象 ....................................................................................................................29 3.更新对象 ....................................................................................................................30 4.保存更新对象 ............................................................................................................31 结语.................................................................................................................................32 NHibernate 之旅(6):探索 NHibernate 中的事务........................................................32 事务概述.........................................................................................................................33 1.新建对象 ....................................................................................................................34 2.删除对象 ....................................................................................................................37 3.更新对象 ....................................................................................................................37 4.保存更新对象 ............................................................................................................38 结语.................................................................................................................................39 NHibernate 之旅(7):初探 NHibernate 中的并发控制................................................39 什么是并发控制?.........................................................................................................39 悲观并发控制(Pessimistic Concurrency) ......................................................40 乐观并发控制(Optimistic Concurrency) ........................................................40 NHibernate 支持乐观并发控制 ..............................................................................40 实例分析.........................................................................................................................41 结语.................................................................................................................................44 NHibernate 之旅(8):巧用组件之依赖对象.......................................................................44 引入.................................................................................................................................45 方案 1:直接添加.........................................................................................................45 方案 2:巧用组件.........................................................................................................45 实例分析.........................................................................................................................46 结语.................................................................................................................................50 NHibernate 之旅(9):探索父子关系(一对多关系)...........................................................50 引入.................................................................................................................................50 NHibernate 中的集合类型 ......................................................................................51 建立父子关系.................................................................................................................51 父子关联映射.................................................................................................................53 结语.................................................................................................................................57 NHibernate 之旅(10):探索父子(一对多)关联查询........................................................57 关联查询引入.................................................................................................................58 一对多关联查询.............................................................................................................58 结语.................................................................................................................................62 NHibernate 之旅(11):探索多对多关系及其关联查询 ....................................................62 多对多关系引入.............................................................................................................63 多对多映射关系.............................................................................................................64 多对多关联查询.............................................................................................................66 结语.................................................................................................................................69 NHibernate 之旅(12):初探延迟加载机制 ........................................................................70 引入.................................................................................................................................70 延迟加载(Lazy Loading) .......................................................................................71 实例分析.........................................................................................................................72 1.一对多关系实例 ........................................................................................................72 2.多对多关系实例 ........................................................................................................74 结语.................................................................................................................................78 NHibernate 之旅(13):初探立即加载机制 ........................................................................78 引入.................................................................................................................................78 立即加载.........................................................................................................................79 实例分析.........................................................................................................................79 1.一对多关系实例 ........................................................................................................79 2.多对多关系实例 ........................................................................................................82 结语.................................................................................................................................86 NHibernate 之旅(14):探索 NHibernate 中使用视图.................................................86 引入.................................................................................................................................87 1.持久化类 ....................................................................................................................87 2.映射文件 ....................................................................................................................88 3.测试 ............................................................................................................................89 结语.................................................................................................................................90 NHibernate 之旅(15):探索 NHibernate 中使用存储过程(上) ................................90 引入.................................................................................................................................90 使用 MyGeneration 生成存储过程........................................................................90 实例分析.........................................................................................................................94 结语.................................................................................................................................97 NHibernate 之旅(16):探索 NHibernate 中使用存储过程(中) ................................97 引入.................................................................................................................................97 实例分析.........................................................................................................................97 结语...............................................................................................................................102 NHibernate 之旅(17):探索 NHibernate 中使用存储过程(下) ..............................102 引入...............................................................................................................................103 实例分析.......................................................................................................................103 拾遗...............................................................................................................................107 结语...............................................................................................................................108 NHibernate 之旅(18):初探代码生成工具使用 ..............................................................108 引入...............................................................................................................................108 代码生成工具...............................................................................................................109 结语...............................................................................................................................117 NHibernate 之旅(19):初探 SchemaExport 工具使用............................................117 引入...............................................................................................................................118 SchemaExport 工具 .............................................................................................118 SchemaUpdate 工具 ............................................................................................119 实例分析.......................................................................................................................119 结语...............................................................................................................................124 NHibernate 之旅(20):再探 SchemaExport 工具使用............................................124 引入...............................................................................................................................125 实例分析.......................................................................................................................125 1.表及其约束 ..............................................................................................................125 2.存储过程、视图 ......................................................................................................130 结语...............................................................................................................................132 NHibernate 之旅(21):探索对象状态 ..............................................................................132 引入...............................................................................................................................132 对象状态.......................................................................................................................133 对象状态转换...............................................................................................................133 结语...............................................................................................................................137 NHibernate 之旅(22):探索 NHibernate 一级缓存...................................................137 引入...............................................................................................................................137 NHibernate 一级缓存介绍 ....................................................................................137 NHibernate 一级缓存管理 ....................................................................................141 结语...............................................................................................................................142 NHibernate 之旅(23):探索 NHibernate 二级缓存(上) ..........................................142 引入...............................................................................................................................143 介绍 NHibernate 二级缓存 ...................................................................................143 NHibernate 二级缓存提供程序 ............................................................................143 实现 NHibernate 二级缓存 ...................................................................................144 结语...............................................................................................................................149 NHibernate 之旅(24):探索 NHibernate 二级缓存(下) ..........................................149 引入...............................................................................................................................149 使用 NHibernate 二级缓存 ...................................................................................150 启用缓存查询...............................................................................................................151 管理 NHibernate 二级缓存 ...................................................................................154 结语...............................................................................................................................158
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值