NHibernate学习

紧接上篇博文继续学习(PS:很多代码我就不重复了,在上篇博文的基础上开始学习NHibernate吧~)

代码还是像往常一样在Word里面总结了,这里就直接Copy,Copy

 建立IRepository接口(注意引入程序集NHibernate)

public interface IRepository<T>
    {       
        void Add(T objectToAdd);
        void AddList(IList<T> list);
        void Delete(T objectToDelete);
        void DeleteList(IList<T> list);
        void Update(T objectToUpdate);
        void UpdateList(IList<T> list);
        IQueryable<T> Query();        
        ISQLQuery DTOQuery(string command);
        /// <summary>
        /// 返回特定的数据 和当前的Repository中对象可以不一致
        
        P SQLQuery<P>(string command);
}

建立Repository类

 public class Repository<T> : IRepository<T>
    {
        public ISessionFactory sessionFactory { get; set; }
        /// <summary>
        /// 增加一个实体
        /// </summary>
        /// <param name="objectToAdd"></param>
        public void Add(T objectToAdd)
        {
            ISession session = GetSession();
            session.Save(objectToAdd);
            session.Flush();
        }
        /// <summary>
        /// 增加多条实体
        /// </summary>
        /// <param name="list"></param>
        public void AddList(IList<T> list)
        {
            if (list==null||list.Count==0)
            {
                return;
            }
            var session = GetSession();
            using (var tran = session.BeginTransaction())
            {
                foreach (var item in list)
                {
                    session.Save(item);
                }
                tran.Commit();
            }
        }
        /// <summary>
        /// 删除一条实体
        /// </summary>
        /// <param name="objectToDelete"></param>
        public void Delete(T objectToDelete)
        {
            ISession session = GetSession();
            session.Delete(objectToDelete);
            session.Flush();
        }
        /// <summary>
        /// 删除多条实体
        /// </summary>
        /// <param name="list"></param>
        public void DeleteList(IList<T> list)
        {
            if (list==null||list.Count==0)
            {
                return;
            }
            var session = GetSession();
            using (var tran=session.BeginTransaction())
            {
                foreach (var item in list)
                {
                    session.Delete(item);
                }
                tran.Commit();               
            }
        }
        /// <summary>
        /// 更新一个实体
        /// </summary>
        /// <param name="objectToUpdate"></param>
        public void Update(T objectToUpdate)
        {
            ISession session = GetSession();
            session.SaveOrUpdate(objectToUpdate);
            session.Flush();
        }
        /// <summary>
        /// 更新多条实体
        /// </summary>
        /// <param name="list"></param>
        public void UpdateList(IList<T> list)
        {
            if (list == null || list.Count == 0)
            {
                return;
            }
            var session = GetSession();
            using (var tran = session.BeginTransaction())
            {
                foreach (var item in list)
                {
                    session.Update(item);
                }
                tran.Commit();
            }
        }
        /// <summary>
        /// 查询一条SQL语句
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public ISQLQuery DTOQuery(string command)
        {
            ISession session = GetSession();
            var query = session.CreateSQLQuery(command);
            query.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(typeof(T)));
            return query;
        }
             
        /// <summary>
        /// 查询所有的数据
        /// </summary>
        /// <returns></returns>
        public IQueryable<T> Query()
        {
            ISession session = GetSession();
            return session.Query<T>();
        }
     
        /// <summary>
        /// 查询总量
        /// </summary>
        /// <typeparam name="P"></typeparam>
        /// <param name="command"></param>
        /// <returns></returns>
        public P SQLQuery<P>(string command)
        {
            P result;
            ISession session = GetSession();
            var query = session.CreateSQLQuery(command);
            result = query.UniqueResult<P>();
            return result;
        }

         /// <summary>
         /// NHibernate中获取Session
         /// </summary>
         /// <returns></returns>
        protected virtual ISession GetSession()
        {
            ISession session = this.sessionFactory.GetCurrentSession();
            if (session==null)
            {
                session = this.sessionFactory.OpenSession();
            }
            return session;
        }
       
    }
    /// <summary>
    /// ISession的扩展方法
    /// </summary>
    public static class ExpandClass
    {
        public static IQueryable<T> Query<T>(this ISession session)
        {
            return new NhQueryable<T>(session.GetSessionImplementation());
        }
}

IWindsorInstaller继承类(PS:需要引入的程序集有:Castle.Windsor.Lifestyles和FluentNHibernate)

 public class NHibernateInstaller: IWindsorInstaller
    {
        public string SQL = ConfigurationManager.ConnectionStrings["SQL"].ConnectionString;
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            //将IRepository和Repository关联
            container.Register(Component.For(typeof(IRepository<>))
                .ImplementedBy(typeof(Repository<>))
                .LifeStyle.HybridPerWebRequestTransient()
                );

            container.Register(Component.For<ISessionFactory>()
                .UsingFactoryMethod(k => BuildSessionFactory(SQL))
                );
        }
        public ISessionFactory BuildSessionFactory(string factoryKey)
        {
            var config = Fluently.Configure()
                  .Database
                  (
                        MsSqlConfiguration.MsSql2008.DefaultSchema("dbo").ConnectionString(factoryKey)
                        .ShowSql()
                  )

                  .Mappings(m => m.FluentMappings.AddFromAssemblyOf<GoodsClassifyEntity>()) //将Mapping文件注入,这个实体类随便写一个就行了

                  .CurrentSessionContext(typeof(LazySessionContext).AssemblyQualifiedName
                  );

            var sessionFactory = config.BuildSessionFactory();
            return sessionFactory;
        }
    }

上面用到一个LazySessionContext类

 public class LazySessionContext : ICurrentSessionContext
    {
        private readonly ISessionFactoryImplementor factory;
        private const string CurrentSessionContextKey = "NHibernateCurrentSession";

        public LazySessionContext(ISessionFactoryImplementor factory)
        {
            this.factory = factory;
        }

        /// <summary>
        /// Retrieve the current session for the session factory.
        /// </summary>
        /// <returns></returns>
        public ISession CurrentSession()
        {
            Lazy<ISession> initializer;
            var currentSessionFactoryMap = GetCurrentFactoryMap();
            if (currentSessionFactoryMap == null ||
                !currentSessionFactoryMap.TryGetValue(factory, out initializer))
            {
                return null;
            }
            return initializer.Value;
        }

        /// <summary>
        /// Bind a new sessionInitializer to the context of the sessionFactory.
        /// </summary>
        /// <param name="sessionInitializer"></param>
        /// <param name="sessionFactory"></param>
        public static void Bind(Lazy<ISession> sessionInitializer, ISessionFactory sessionFactory)
        {
            var map = GetCurrentFactoryMap();
            map[sessionFactory] = sessionInitializer;
        }

        /// <summary>
        /// Unbind the current session of the session factory.
        /// </summary>
        /// <param name="sessionFactory"></param>
        /// <returns></returns>
        public static ISession UnBind(ISessionFactory sessionFactory)
        {
            var map = GetCurrentFactoryMap();
            var sessionInitializer = map[sessionFactory];
            map[sessionFactory] = null;
            if (sessionInitializer == null || !sessionInitializer.IsValueCreated) return null;
            return sessionInitializer.Value;
        }

        /// <summary>
        /// Provides the CurrentMap of SessionFactories.
        /// If there is no map create/store and return a new one.
        /// </summary>
        /// <returns></returns>
        private static IDictionary<ISessionFactory, Lazy<ISession>> GetCurrentFactoryMap()
        {
            IDictionary<ISessionFactory, Lazy<ISession>> currentFactoryMap = null;
            if (HttpContext.Current != null)
            {
                currentFactoryMap = (IDictionary<ISessionFactory, Lazy<ISession>>)
                                        HttpContext.Current.Items[CurrentSessionContextKey];
                if (currentFactoryMap == null)
                {
                    currentFactoryMap = new Dictionary<ISessionFactory, Lazy<ISession>>();
                    HttpContext.Current.Items[CurrentSessionContextKey] = currentFactoryMap;
                }
            }
            else //为了application Job 执行,由于Job执行时没有HttpContext.Current 
            {
                if (CurrentFactoryMap == null)
                {
                    CurrentFactoryMap = new Dictionary<ISessionFactory, Lazy<ISession>>();
                }
                currentFactoryMap = CurrentFactoryMap;
            }
            return currentFactoryMap;
        }

        private static IDictionary<ISessionFactory, Lazy<ISession>> CurrentFactoryMap;
    }

数据库连接配置:

<add name="SQL" connectionString="server=.;database=MyTry;integrated security=true;"/>

 NHibernate映射需要写一个实体类和一个映射文件,不写映射的话,就只能用SQL语句查询,而不能使用NHibernate查,所以我们先搭建一个映射,让实体和表关联,

下面就介绍下Goods表和GoodsClassify表在NHibernate中的使用:

Goods实体文件:

 [Serializable]
    public class GoodsEntity
    {
        public virtual int ID { get; set; }
        public virtual string GoodName { get; set; }
        public virtual int ClassID { get; set; }
        public virtual DateTime? CreateTime { get; set; }
   }

Goods映射文件:

public class GoodsMap:ClassMap<GoodsEntity>
    {
        public GoodsMap()
        {
            Table("Goods");
            Id(x => x.ID).GeneratedBy.Assigned();
            Map(x => x.GoodName);
            Map(x => x.ClassID);
            Map(x => x.CreateTime);
        }
    }

GoodsClassify实体文件:

[Serializable]
    public class GoodsClassifyEntity
    {
        public virtual int ClassID { get; set; }
        public virtual string CategoryName { get; set; }
        public virtual DateTime? CreateTime { get; set; }
    }

GoodsClassify映射文件:

 public class GoodsClassifyMap : ClassMap<GoodsClassifyEntity>
    {
        public GoodsClassifyMap()
        {
            Table("GoodsClassify");
            Id(x => x.ClassID).GeneratedBy.Assigned();
            Map(x=>x.CategoryName);
            Map(x=>x.CreateTime);
        }
    }

以上是连接单个数据库,我们还可以设置连接多个数据库:

1>.首先新建一个Repository子类TestRepository继承Repository并重写GetSession

 public class TestRepository<T>:Repository<T>
    {
        string key = "TestConnection";//这个注入的啥获取的时候Key就是啥       
        protected override ISession GetSession()
        {
            ISessionFactory factory = IocContainer.Container.Resolve<ISessionFactory>(key);
            ISession session=factory.GetCurrentSession();
            if (session==null)
            {
                session = factory.OpenSession();
            }
            return session;
        }              

    }

2.>在NHIbernate内注入其它数据库,修改下NHibernateInstaller类

 public class NHibernateInstaller: IWindsorInstaller
    { 
        public string MyTry="MyTryConnection";
        public string Test = "TestConnection";
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            //将IRepository和Repository关联
            container.Register(Component.For(typeof(IRepository<>))
                .ImplementedBy(typeof(Repository<>))
                .LifeStyle.HybridPerWebRequestTransient()
                );

            container.Register(Component.For<ISessionFactory>()
                                .UsingFactoryMethod(k => BuildSessionFactory(MyTry)));
            //将其它数据库进行注入,别忘了结尾加Named
            container.Register(Component.For<ISessionFactory>()
                           .UsingFactoryMethod(k => BuildSessionFactory(Test)).Named(Test));            

        }
        public ISessionFactory BuildSessionFactory(string factoryKey)
         {
            var con = ConfigurationManager.ConnectionStrings[factoryKey];
            var config = Fluently.Configure()
                  .Database
                  (
                        MsSqlConfiguration.MsSql2008.DefaultSchema("dbo").ConnectionString(con.ConnectionString)
                        .ShowSql()
                  )

                  .Mappings(m => m.FluentMappings.AddFromAssemblyOf<GoodsEntity>()) //将Mapping文件注入

                  .CurrentSessionContext(typeof(LazySessionContext).
                  AssemblyQualifiedName
                  );

            var sessionFactory = config.BuildSessionFactory();
            return sessionFactory;
        }
}

3>.将TargetInstall类去掉,添加IocContainer自定义容器类

public class IocContainer
    {
        private const string Interceptors = "Demo2.ServiceInterceptor";
        private static IWindsorContainer container;
        public static IWindsorContainer Container
        {
            get
            {
                if (container==null)
                {
                    container = new WindsorContainer();
                    container.Register(Classes.FromThisAssembly() //在哪里找寻接口或类

                           .BasedOn<IController>() //实现IController接口

                           .If(Component.IsInSameNamespaceAs<HomeController>()) //与HomeController在同一个命名空间

                           .If(t => t.Name.EndsWith("Controller")) //以"Controller"结尾

                           .Configure(c => c.LifestylePerWebRequest()));//每次请求创建一个Controller实例


                    var componentList = new List<IRegistration>();

                    var classes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsVisible).Where(p => ((ServiceAttribute)p.GetCustomAttributes(typeof(ServiceAttribute), false).FirstOrDefault()) != null).ToList();

                    foreach (var item in classes)

                    {
                        var name = item.FullName;
                        var baseType = ((ServiceAttribute)item.GetCustomAttributes(typeof(ServiceAttribute), false).First()).BaseType;

                        componentList.Add(Component.For(baseType).ImplementedBy(item).Named(name).Interceptors(Interceptors));
                    }

                    container.Register(componentList.ToArray());
                }
                return container;
            }
        }
    }

4>.在Global修改如下

  public class MvcApplication : System.Web.HttpApplication
    {        
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            BootstrapContainer();
        }
        public IWindsorContainer Container
        {
            get { return IocContainer.Container; }
        }
        private void BootstrapContainer()
        {
            //初始化一个IOC容器
           Container.Install(FromAssembly.This());
            //完成IWindsorInstaller接口中的注册
            ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(Container.Kernel));

        }
    }

5>.在Goods里面进行调用

[Service(BaseType =typeof(IGoods))]
 public class Goods : IGoods
{
rivate IRepository<GoodsEntity> repository;
        IRepository<UsersEntity> usersRepository;//其余数据库创建对象,直接new即可。注意里面填写的UsersEntity实体是否和方法获取的实体对应
 public Goods(IRepository<GoodsEntity> repository) //声明对象
 {
            this.repository = repository;
            this.usersRepository = new TestRepository<UsersEntity>();
}
   //测试方法
    public List<string> GetUserName(int id)
        {
            List<string> list = new List<string>();                    
            
            var model= usersRepository.Query().FirstOrDefault(c=>c.UserID==id);
            var model2 = repository.Query().FirstOrDefault(c=>c.ID==id);
            if (model != null)
            {
                list.Add(model.UserName);
                list.Add(model2.GoodName);
            }
            return list;
        }

}

好了,NHibernate大概就这么多了。

posted @ 2017-08-01 18:03  shuai7boy  阅读(348)  评论(0编辑  收藏  举报