Asp.Net大型项目实践(4)-用NHibernate保存和查询我们的业务领域对象之NHibernate的Session管理与初始化(附源码)

  NHibernate的Session和Asp.Net的Session是两码事,大家不要混淆了。NHibernate的Session是拿来干啥的?对用用过Linq2Sql的同学,可以把它理解成DataContext。要被持久化的对象都要放在Session里托管。Session同时也是一个缓存,比如在一定范围内你通过NHibernate ,Get了一个User ,当你再次Get同样的这个User的时候NHibernate就不会去操作数据库,而会直接从Session缓存中取出第一次获得的User。

  1. 为了充分利用NHibernate的延迟加载和它缓存机制,我们应该把Session的生命周期合理控制,比如在WCF应用中我们应该把Session绑定在一次通讯请求里,在Asp.netMVC中我们最好把Session的生命周期绑定在一次Action里。由于我们的系统设计将来会用到WCF或其他请求形式,所以我们做一个接口:
    using System;
    using NHibernate;

    namespace Demo.HIS.FrameWork.Repository.NHb
    {
    public interface ISessionStorage
    {
    ISession Get();
    void Set(ISession value);
    }
    }
    注意添加引用NHibernate.dll,目前使用的版本是NHibernate-2.1.0
  2. 因为目前主要我们还是用Asp.net MVC 所以新建一个类HttpSessionStorage实现接口ISessionStorage:
    代码
    using NHibernate;
    using System.Web;

    namespace Demo.HIS.FrameWork.Repository.NHb
    {
    public class HttpSessionStorage : ISessionStorage
    {
    #region ISessionStorage 成员

    public NHibernate.ISession Get()
    {
    return (ISession)HttpContext.Current.Items["NhbSession"];
    }

    public void Set(ISession value)
    {
    if (value != null)
    {
    HttpContext.Current.Items.Add(
    "NhbSession", value);
    }
    }

    #endregion
    }
    }
    这里我们就把NHibernate的Session的生命周期和一次Action请求( HttpContext.Current.Item)绑定在一起了,注意添加引用System.Web
  3. 我们新建一个类SessionBuilder去初始化NHibernate的Session:
    代码
    namespace Demo.HIS.FrameWork.Repository.NHb
    {
    public static class SessionBuilder
    {
    private static object locker = new object();
    private static Configuration configuration = null;
    private static ISessionFactory sessionFactory = null;
    public static ISessionStorage sessionStorage { set; get; }

    private static void CreateConfiguration()
    {
    // HibernatingRhinos.NHibernate.Profiler.Appender.NHibernateProfiler.Initialize();//查看HQL生成的SQL
    //configuration = new Configuration().Configure(System.Web.HttpContext.Current.Request.PhysicalApplicationPath + "Configuration\\hibernate.cfg.xml");
    configuration = new Configuration().Configure();
    }

    public static Configuration Configuration
    {
    get
    {
    lock (locker)
    {
    if (configuration == null)
    {
    CreateConfiguration();
    }
    return configuration;
    }
    }
    set { configuration = value; }
    }

    internal static ISessionFactory SessionFactory
    {
    get
    {
    if (sessionFactory==null)
    {
    if (Configuration == null)
    {
    CreateConfiguration();
    }
    lock (locker)
    {
    sessionFactory
    = Configuration.BuildSessionFactory();
    }
    }

    return sessionFactory;
    }
    }

    public static ISession CreateSession()
    {
    ISession s
    = sessionStorage.Get();
    if (s == null)
    {
    s
    = SessionFactory.OpenSession();
    sessionStorage.Set(s);
    }
    return s;
    }

    }
    }

    注意configuration = new Configuration().Configure(); 这句读取NHibernate的配置文件,配置文件的位置必须放在网站(DemoHisSite)根目录,且命名为hibernate.cfg.xml,如果你想把这个配置文件放在别的位置或取其他名字,请看代码里注释掉的那行。

  4. NHibernate配置文件
    位置:

    内容:

    代码
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <configSections>
    <section name="hibernate-configuration"
    type
    ="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
    </configSections>
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
    <session-factory>
    <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
    <property name="connection.connection_string">
    User ID=dawnhis;Password=his;Data Source=dawhisdb
    </property>
    <property name="show_sql">true</property>
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
    <property name="use_outer_join">true</property>
    <property name="command_timeout">10</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
    <mapping assembly="Infrastructure.Repositories"/>

    </session-factory>
    </hibernate-configuration>
    </configuration>

    具体配置节的含义,自己找资料看吧这里就不罗嗦了

  5. 在Global.asax指定ISessionStorage具体实例:

    代码
    namespace Demo.HIS.MVC
    {
    public class DemoHISApplication : HttpApplication
    {
    protected virtual void OnStart()
    {
    initSessionBuilder();
    }

    private void initSessionBuilder()
    {
    SessionBuilder.sessionStorage = new HttpSessionStorage();//这里创建Session实例
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = "" } // Parameter defaults
    );

    }
    protected void Application_Start()
    {
    OnStart();
    }
    }
    }

    注意我这里更改了下Global.asax的引用:

    <%@ Application Inherits="Demo.HIS.MVC.DemoHISApplication" Language="C#" %>

源码下载:HISDemo-2.rar

posted on 2009-12-25 09:55  传说中的弦哥  阅读(13466)  评论(10编辑  收藏  举报

导航