[转]NHibernate第一个实例(基于NHibernate-3.3.2)

最近因为项目的需要,数据层想换成NHibernate,我以前在做JAVA时虽曾接触过Hibernate,但好些年过去了,做第一个实例居然费了我好些精力,现把成功的例子贴出来。

1、建立数据表和实体对象

数据库是用的MSSQL2008,建表语句就不贴了,总共就3个字段。下面是实体对象代码

using System;

namespace Example.Domain
{
    public class Item
    {
        private int id;
        private decimal price;
        private string description;

        public virtual int Id
        {
            get { return id; }
            set { id = value; }
        }

        public virtual decimal Price
        {
            get { return price; }
            set { price = value; }
        }

        public virtual string Description
        {
            get { return description; }
            set { description = value; }
        }
    }
}

2、在Item对象的同一项目(同一目录)下新建一个与实体对象同名的XML文件,以“hbm.xml”为扩展名。如:Item.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
                   assembly="Example.Domain"
                   namespace="Example.Domain">
    <!--
        Class has to be non-lazy because Medium Trust Level restrictions
        prevent proxy generation from working.
    -->
    <class name="Item" table="Item" lazy="false">
        <id name="Id">
            <generator class="native" />
        </id>
        <property name="Price" />
        <property name="Description" />
    </class>
</hibernate-mapping>

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

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

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

3、web.config中进行配置

 

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" requirePermission="false"/>
        <!-- Important under Medium Trust -->
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/>
        <!-- Important under Medium Trust -->
    </configSections>
    <appSettings/>
    <connectionStrings/>
    <system.web>

        <compilation debug="true">
        </compilation>
        <authentication mode="Windows"/>
        <pages enableViewState="false" enableViewStateMac="false">
        </pages>
        <httpModules>
            <add name="CurrentSessionModule" type="NHibernate.Example.Web.CurrentSessionModule"/>
        </httpModules>
    </system.web>
  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
        <bytecode-provider type="null"/>
        <session-factory>
            <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider, NHibernate</property>
            <property name="connection.connection_string">
        Data Source=PC-20110811NRNE\SQLEXPRESS;initial catalog=Northwind;Integrated Security=true;User ID=user1;Password=pwd1
      </property>
            <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
            <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
      <property name="current_session_context_class">managed_web</property>
<span style="BACKGROUND-COLOR: #ff6666"><span style="BACKGROUND-COLOR: #ffffff">      <property name="proxyfactory.factory_class">NHibernate.Bytecode.DefaultProxyFactoryFactory,NHibernate</property>
      <mapping assembly="Example.Domain"/>
</span></span>    </session-factory>
    </hibernate-configuration>
    <log4net>
        <!-- Define some output appenders -->
        <appender name="trace" type="log4net.Appender.TraceAppender, log4net">
            <layout type="log4net.Layout.PatternLayout,log4net">
                <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n"/>
            </layout>
        </appender>
        <appender name="console" type="log4net.Appender.ConsoleAppender, log4net">
            <layout type="log4net.Layout.PatternLayout,log4net">
                <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n"/>
            </layout>
        </appender>
        <root>
            <priority value="WARN"/>
            <appender-ref ref="trace"/>
        </root>
    </log4net>
</configuration>

 

标红色背景的是要特别注意的地方。3.3.2版本的测试通过,从网上搜集的先前版本的例子都不正常了。

 

4、ISeesion调用代码

using System.Web;
using System.Web.Hosting;
using NHibernate.Cfg;
using Example.Domain;

namespace NHibernate.Example.Web
{
    public class ExampleApplication : HttpApplication
    {
        public static readonly Configuration Configuration;
        public static readonly ISessionFactory SessionFactory;

        static ExampleApplication()
        {
            log4net.Config.XmlConfigurator.Configure();
            Configuration = new Configuration();
            string nhConfigPath = HostingEnvironment.MapPath("~/App_Data/hibernate.cfg.xml");
            if (File.Exists(nhConfigPath))
            {
                Configuration.Configure(nhConfigPath);
            }
            SessionFactory = Configuration.Configure().BuildSessionFactory();
        }
        
        public static ISession GetCurrentSession()
        {
            return SessionFactory.GetCurrentSession();
        }
    }
}

还有个类:

using System;
using System.Web;
using NHibernate.Context;

namespace NHibernate.Example.Web
{
    public class CurrentSessionModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(Application_BeginRequest);
            context.EndRequest += new EventHandler(Application_EndRequest);
        }

        public void Dispose()
        {

        }

        private void Application_BeginRequest(object sender, EventArgs e)
        {
            ManagedWebSessionContext.Bind(HttpContext.Current, ExampleApplication.SessionFactory.OpenSession());
        }

        private void Application_EndRequest(object sender, EventArgs e)
        {
            ISession session = ManagedWebSessionContext.Unbind(HttpContext.Current, ExampleApplication.SessionFactory);

            if (session.Transaction.IsActive)
            {
                session.Transaction.Rollback();
            }

            if (session != null)
            {
                session.Close();
            }
        }
    }
}

5、数据层封装类

using System;
using System.Collections.Generic;
using Example.Domain;

namespace NHibernate.Example.Web.Persistence
{
    public class ItemList
    {
        public IList<Item> GetAllItems()
        {
            return ExampleApplication.GetCurrentSession().CreateQuery("from Item").List<Item>();
        }
        
        public void UpdateItem(Item item)
        {
            ExampleApplication.GetCurrentSession().SaveOrUpdateCopy(item);
        }
        
        public void DeleteItem(Item item)
        {
            ISession session = ExampleApplication.GetCurrentSession();
            session.Delete(session.Load(typeof(Item), item.Id));
        }
        
        public void InsertItem(Item item)
        {
            ExampleApplication.GetCurrentSession().Save(item);
        }
    }
}

以上代码在我本机测试通过。

 

 

posted @ 2014-11-24 13:35  Net-Spider  阅读(144)  评论(0)    收藏  举报